コード例 #1
0
ファイル: CAeonInterface.cpp プロジェクト: kronosaur/Hexarc
CString CAeonInterface::EncodeFilePathComponent (const CString &sValue)

//	EncodeFilePathComponent
//
//	Encodes a file path component by replacing any invalid characters with ~hh
//	(where hh is the hexcode).

	{
	char *pPos = sValue.GetParsePointer();
	char *pEndPos = pPos + sValue.GetLength();
	CStringBuffer Output;

	while (pPos < pEndPos)
		{
		if (!strIsASCIIAlpha(pPos)					//	alpha
				&& !strIsDigit(pPos)				//	numbers
				&& *pPos != '-'
				&& *pPos != '_'
				&& *pPos != '.'
				&& *pPos != '~'
				&& !strIsASCIIHigh(pPos))			//	unicode characters
			{
			CString sChar = strPattern("~%x", (DWORD)(BYTE)*pPos);
			Output.Write(sChar);
			}
		else
			Output.Write(pPos, 1);

		pPos++;
		}

	//	Done

	return CString::CreateFromHandoff(Output);
	}
コード例 #2
0
ファイル: IComplexDatum.cpp プロジェクト: kronosaur/Hexarc
bool CComplexDateTime::CreateFromString (const CString &sString, CDateTime *retDateTime)

//	CreateFromString
//
//	Reverse of AsString

	{
	char *pPos = sString.GetParsePointer();

	int iYear = strParseInt(pPos, 0, &pPos);
	if (iYear < 1 || iYear > 30827)
		return false;

	if (*pPos++ != '-')
		return false;

	int iMonth = strParseInt(pPos, 0, &pPos);
	if (iMonth < 1 || iMonth > 12)
		return false;

	if (*pPos++ != '-')
		return false;

	int iDay = strParseInt(pPos, 0, &pPos);
	if (iDay < 1 || iDay > CDateTime::GetDaysInMonth(iMonth, iYear))
		return false;

	if (*pPos++ != 'T')
		return false;

	int iHour = strParseInt(pPos, -1, &pPos);
	if (iHour < 0 || iHour > 23)
		return false;

	if (*pPos++ != ':')
		return false;

	int iMinute = strParseInt(pPos, -1, &pPos);
	if (iMinute < 0 || iMinute > 59)
		return false;

	if (*pPos++ != ':')
		return false;

	int iSecond = strParseInt(pPos, -1, &pPos);
	if (iSecond < 0 || iSecond > 59)
		return false;

	if (*pPos++ != '.')
		return false;

	int iMillisecond = strParseInt(pPos, -1, &pPos);
	if (iMillisecond < 0 || iMillisecond > 999)
		return false;

	//	Done

	*retDateTime = CDateTime(iDay, iMonth, iYear, iHour, iMinute, iSecond, iMillisecond);
	return true;
	}
コード例 #3
0
ファイル: CAeonRowValue.cpp プロジェクト: gmoromisato/Hexarc
void CAeonRowValue::SerializeKey (IByteStream &Stream, const CString &sKey, DWORD *retdwSize)

//	SerializeKey
//
//	Serializes a key and returns the serialized size.
//
//	DWORD	key size
//	BYTES[]	key (padded to DWORD align)

	{
	DWORD dwKeySize = sKey.GetLength();

	//	Write out the key length

	Stream.Write(&dwKeySize, sizeof(DWORD));

	//	Write out the key (add 1 for NULL termination)

	Stream.Write(sKey.GetParsePointer(), dwKeySize + 1);

	//	Save padding

	DWORD dwZero = 0;
	DWORD dwAlignedKeySize = AlignUp(dwKeySize + 1, (DWORD)sizeof(DWORD));
	Stream.Write(&dwZero, dwAlignedKeySize - (dwKeySize + 1));

	//	Done

	if (retdwSize)
		*retdwSize = sizeof(DWORD) + dwAlignedKeySize;
	}
コード例 #4
0
ファイル: CAeonInterface.cpp プロジェクト: kronosaur/Hexarc
bool CAeonInterface::ParseTableFilePath (const CString &sPath, CString *retsTable, CString *retsFilePath, CString *retsError)

//	ParseTableFilePath
//
//	Parses a filePath

	{
	char *pPos = sPath.GetParsePointer();
	char *pEndPos = pPos + sPath.GetLength();

	//	First character must be a slash because we need an absolute path

	if (*pPos != '/')
		{
		if (retsError)
			*retsError = STR_ERROR_ABSOLUTE_PATH_REQUIRED;
		return false;
		}

	pPos++;

	//	The first segment is the table name

	char *pStart = pPos;
	while (pPos < pEndPos && *pPos != '/')
		pPos++;

	CString sTable(pStart, pPos - pStart);
	if (sTable.IsEmpty())
		{
		if (retsError)
			*retsError = STR_ERROR_NO_TABLE_IN_PATH;
		return false;
		}

	//	We have the table name

	if (retsTable)
		*retsTable = sTable;

	//	If we've reached the end, then we have an empty path

	if (pPos >= pEndPos)
		{
		if (retsFilePath)
			*retsFilePath = CString("/", 1);
		return true;
		}

	//	filePath starts with a slash and goes to the end.

	if (retsFilePath)
		*retsFilePath = CString(pPos, (int)(pEndPos - pPos));

	//	Done

	return true;
	}
コード例 #5
0
ファイル: HTML.cpp プロジェクト: gmoromisato/Hexarc
void htmlWriteText (const CString &sText, IByteStream &Output)

//	htmlWriteText
//
//	Writes text, escaping all appropriate HTML characters.
//
//	NOTE: This is only for the text content of HTML element; for escaping
//	attribute values, use htmlWriteAttributeValue

	{
	char *pPos = sText.GetParsePointer();
	char *pPosEnd = pPos + sText.GetLength();
	htmlWriteText(pPos, pPosEnd, Output);
	}
コード例 #6
0
ファイル: AI1.cpp プロジェクト: gmoromisato/Hexarc
CString ExecuteUploadCertificate (CSocket &theSocket, const CString &sCmd)
	{
	char *pPos = sCmd.GetParsePointer() + STR_UPLOAD_CERTIFICATE_PREFIX.GetLength();
	
	//	Skip whitespace

	while (*pPos == ' ')
		pPos++;
	
	//	Get the filespec

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

	CString sFilespec(pStart, pPos - pStart);

	//	Upload

	return UploadFile(theSocket, CMD_UPLOAD, CString("/Arc.certificates"), sFilespec);
	}
コード例 #7
0
ファイル: AI1.cpp プロジェクト: gmoromisato/Hexarc
CString ExecuteUpload (CSocket &theSocket, const CString &sCmd)
	{
	char *pPos = sCmd.GetParsePointer() + STR_UPLOAD_PREFIX.GetLength();
	
	//	Get the filePath

	if (*pPos == '\"')
		pPos++;

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

	CString sFilePath(pStart, pPos - pStart);
	if (*pPos != '\0')
		pPos++;

	if (*pPos == '\"')
		pPos++;

	//	Skip whitespace

	while (*pPos == ' ')
		pPos++;
	
	//	Get the filespec

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

	CString sFilespec(pStart, pPos - pStart);

	//	Load the file

	return UploadFile(theSocket, CMD_UPLOAD, sFilePath, sFilespec);
	}
コード例 #8
0
ファイル: CAeonInterface.cpp プロジェクト: kronosaur/Hexarc
CString CAeonInterface::FilespecToFilePath (const CString &sFilespec)

//	FilespecToFilePath
//
//	Converts a filespec to an Aeon filePath. We convert \ to / and escape all
//	characters that are not valid Aeon path characters.

	{
	char *pPos = sFilespec.GetParsePointer();
	char *pEndPos = pPos + sFilespec.GetLength();
	CStringBuffer Output;

	while (pPos < pEndPos)
		{
		if (*pPos == '\\')
			Output.Write("/", 1);
		else if (!strIsASCIIAlpha(pPos)				//	alpha
				&& !strIsDigit(pPos)				//	numbers
				&& *pPos != '-'
				&& *pPos != '_'
				&& *pPos != '.'
				&& *pPos != '~'
				&& !strIsASCIIHigh(pPos))			//	unicode characters
			{
			CString sChar = strPattern("_%x_", (DWORD)(BYTE)*pPos);
			Output.Write(sChar);
			}
		else
			Output.Write(pPos, 1);

		pPos++;
		}

	//	Done

	return CString::CreateFromHandoff(Output);
	}
コード例 #9
0
ファイル: CMnemosynthDb.cpp プロジェクト: gmoromisato/Hexarc
void CMnemosynthDb::ParseEndpointName (const CString &sEndpoint, CString *retsMachine, CString *retsModule)

//	ParseEndpointName
//
//	Parses out an endpoint name into machine and module

	{
	char *pPos = sEndpoint.GetParsePointer();

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

	if (*pPos == '\0')
		return;

	if (retsMachine)
		*retsMachine = CString(pStart, pPos - pStart);

	pPos++;

	if (retsModule)
		*retsModule = CString(pPos);
	}
コード例 #10
0
ファイル: XMLParser.cpp プロジェクト: gmoromisato/Hexarc
CString ResolveEntity (ParserCtx *pCtx, const CString &sName, bool *retbFound)

//	ResolveEntity
//
//	Resolves the entity from the parser table

	{
	*retbFound = true;
	CString sResult;

	//	Check to see if the name is one of the standard entities

	CString sNameLC = strToLower(sName);
	if (strEquals(sNameLC, ENTITY_AMP))
		return ENTITY_AMP_SUB;
	else if (strEquals(sNameLC, ENTITY_LT))
		return ENTITY_LT_SUB;
	else if (strEquals(sNameLC, ENTITY_GT))
		return ENTITY_GT_SUB;
	else if (strEquals(sNameLC, ENTITY_QUOT))
		return ENTITY_QUOT_SUB;
	else if (strEquals(sNameLC, ENTITY_APOS))
		return ENTITY_APOS_SUB;

	//	If the entity is a hex number, then this is a character

	char *pPos = sName.GetParsePointer();
	if (*pPos == '#')
		{
		pPos++;
		if (*pPos == 'x' || *pPos == 'X')
			{
			*pPos++;
			char chChar = (char)strParseIntOfBase(pPos, 16, 0x20, NULL, NULL);
			return CString(&chChar, 1);
			}
		else
			{
			char chChar = (char)strParseInt(pPos, 0x20);
			return CString(&chChar, 1);
			}
		}

	//	Otherwise, it is a general attribute

	bool bFound;
	CString sValue = pCtx->LookupEntity(sName, &bFound);
	if (bFound)
		{
		//	Parse the value to resolve embedded entities

		ParserCtx SubCtx(pCtx, sValue);

		ParseToken(&SubCtx, ParseEntityState);
		if (SubCtx.iToken == tkText)
			sResult = SubCtx.sToken;
		else
			{
			bFound = false;
			sResult = sName;
			}
		}

	if (retbFound)
		*retbFound = bFound;

	return sResult;
	}
コード例 #11
0
bool CCryptosaurEngine::ValidateUsername (const CString &sUsername, CString *retsError)

//	ValidateUsername
//
//	Make sure that the username is valid. Usernames can have any character
//	except ASCII control codes and must have at least one printable character.
//
//	Also, usernames may not start with '#', '&', '@', '$', '%', or '['.
//
//	If valid we return TRUE.

	{
	bool bLeadingWhitespace = false;
	bool bTrailingWhitespace = false;
	bool bDoubleWhitespace = false;
	bool bHasPrintableChars = false;
	char *pPos = sUsername.GetParsePointer();
	char *pPosEnd = pPos + sUsername.GetLength();

	//	Can't lead with certain symbols

	if (*pPos == '[' || *pPos == '#' || *pPos == '&' || *pPos == '$' || *pPos == '@' || *pPos == '%')
		{
		*retsError = ERR_INVALID_LEADING_CHAR;
		return false;
		}

	//	Check the rest of the name

	int iCount = 0;
	while (pPos < pPosEnd)
		{
		if (strIsASCIIControl(pPos))
			{
			*retsError = ERR_CANT_HAVE_CONTROL_CHARS;
			return false;
			}

		//	Is this a printable char?

		UTF32 dwCodePoint = strParseUTF8Char(&pPos, pPosEnd);
		bool bIsPrintableChar = strIsPrintableChar(dwCodePoint);

		//	If this is not printable and we haven't yet seen a printable char
		//	then we have a leading whitespace

		if (!bIsPrintableChar && !bHasPrintableChars)
			bLeadingWhitespace = true;

		//	We have at least one printable char

		if (bIsPrintableChar)
			bHasPrintableChars = true;

		//	If the previous character was also whitespace, then that's an error

		else if (bTrailingWhitespace)
			bDoubleWhitespace = true;

		bTrailingWhitespace = !bIsPrintableChar;

		if (bIsPrintableChar)
			iCount++;
		}

	//	Printable characters

	if (iCount < 3)
		{
		*retsError = ERR_MUST_HAVE_PRINTABLE_CHARS;
		return false;
		}

	//	Leading or trailing whitespace

	if (bLeadingWhitespace || bTrailingWhitespace)
		{
		*retsError = ERR_INVALID_WHITESPACE;
		return false;
		}

	//	Double whitespace

	if (bDoubleWhitespace)
		{
		*retsError = ERR_TOO_MUCH_WHITESPACE;
		return false;
		}

	//	Done

	return true;
	}
コード例 #12
0
ファイル: AI1.cpp プロジェクト: gmoromisato/Hexarc
CString ExecuteHTTPGet (const CString &sInput)
	{
	//	Parse the input

	char *pPos = sInput.GetParsePointer() + STR_HTTP_GET_PREFIX.GetLength();

	//	Parse the URL

	CString sHost;
	CString sPath;
	if (!urlParse(pPos, NULL, &sHost, &sPath))
		return CString("Invalid URL.");

	//	If no host, then local host

	if (sHost.IsEmpty())
		sHost = CString("localhost");

	//	Connect

	CSocket theSocket;
	if (!theSocket.Connect(sHost, 80))
		return strPattern("Unable to connect to: %s.", sHost);

	//	Compose a request

	CHTTPMessage Request;
	Request.InitRequest(CString("GET"), sPath);
	Request.AddHeader(HEADER_HOST, sHost);
	Request.AddHeader(HEADER_CONNECTION, CString("keep-alive"));
#ifdef DEBUG_REQUEST_FRAGMENT_X
	Request.AddHeader(HEADER_USER_AGENT, CString("AI1/1.0 (This is a test of the header parsing system in Hexarc. There is probably a bug in which splitting the header across packets will cause failure of the HTTP parsing engine.)"));
#else
	Request.AddHeader(HEADER_USER_AGENT, CString("AI1/1.0"));
#endif

	//	Send the request

	CBuffer Buffer(4096);
	Request.WriteToBuffer(Buffer);

#ifdef DEBUG_REQUEST_FRAGMENT
	int iTotalLen = Buffer.GetLength();
	int iSplit = 105;

	if (iSplit < iTotalLen)
		{
		printf("Split at %d bytes\n", iSplit);
		CString sPart(Buffer.GetPointer(), iSplit);
		printf("%s\n", (LPSTR)sPart);

		theSocket.Write(Buffer.GetPointer(), iSplit);
		::Sleep(10);
		theSocket.Write(Buffer.GetPointer() + iSplit, iTotalLen - iSplit);
		}
	else
		theSocket.Write(Buffer.GetPointer(), Buffer.GetLength());
#else
	theSocket.Write(Buffer.GetPointer(), Buffer.GetLength());
#endif

	//	Now read the response. We build up a buffer to hold it.

	CHTTPMessage Response;
	CBuffer ResponseBuff;

	//	Keep reading until we've got enough (or until the connection drops)

	while (!Response.IsMessageComplete())
		{
		CBuffer TempBuffer(8192);

		//	Read

		int iBytesRead = theSocket.Read(TempBuffer.GetPointer(), 8192);
		TempBuffer.SetLength(iBytesRead);

		//	If we're no making progress, then we're done

		if (iBytesRead == 0)
			return strPattern("Unable to read entire message.");

		//	Add to entire buffer

		ResponseBuff.Write(TempBuffer.GetPointer(), iBytesRead);

		//	Parse to see if we're done

		if (!Response.InitFromPartialBuffer(TempBuffer))
			return strPattern("Unable to parse HTTP message.");
		}

	//	Done

	theSocket.Disconnect();

	return CString(ResponseBuff.GetPointer(), ResponseBuff.GetLength());
	}
コード例 #13
0
ファイル: CEnvelopeKey.cpp プロジェクト: gmoromisato/Hexarc
bool CSSLEnvelopeKey::InitFromPEM (IMemoryBlock &Data, const CString &sPassphrase, bool bKeepRaw, CString *retsError)

//	InitFromPEM
//
//	Loads the first key from the given PEM file.

	{
	CleanUp();

	//	Make sure OpenSSL is initialized.

	if (!g_SSLGlobal.Init())
		return false;

	//	Keep parsing until we find a key

	int iPos = 0;
	while (CSSLCert::HasPEMSection(Data, iPos))
		{
		CString sData;
		CString sType;

		if (!CSSLCert::ParsePEMSection(Data, iPos, &sData, &sType, &iPos))
			{
			if (retsError) *retsError = ERR_CANT_PARSE_PEM;
			return false;
			}

		//	We skip any types that we don't understand. This is not an error, 
		//	since we often store private keys and other things in a PEM file.

		if (!IsKeyPEMSection(sType))
			continue;

		//	Create BIO stream for the section

		CMemoryBIO SectionData(sData);

		//	Create the key

		EVP_PKEY *pKey = PEM_read_bio_PrivateKey(SectionData, NULL, NULL, sPassphrase.GetParsePointer());
		if (!pKey)
			{
			if (retsError) *retsError = ERR_CANT_PARSE_KEY;
			return false;
			}

		//	Create

		m_pData = new SEKey;
		m_pData->pKey = pKey;
		if (bKeepRaw)
			m_pData->sPEMData = sData;

		//	We load the first key we find, so we're done.

		break;
		}

	//	If we didn't find a key, then we return an error

	if (m_pData == NULL)
		{
		if (retsError) *retsError = ERR_NO_KEY_FOUND;
		return false;
		}

	//	Success

	return true;
	}
コード例 #14
0
ファイル: AI1.cpp プロジェクト: gmoromisato/Hexarc
CString ExecuteUploadPackage (CSocket &theSocket, const CString &sCmd)
	{
	int i;
	char *pPos = sCmd.GetParsePointer() + STR_UPLOAD_PACKAGE_PREFIX.GetLength();
	
	//	Get the package name

	if (*pPos == '\"')
		pPos++;

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

	CString sPackageName(pStart, pPos - pStart);
	if (*pPos != '\0')
		pPos++;

	if (*pPos == '\"')
		pPos++;

	//	Skip whitespace

	while (*pPos == ' ')
		pPos++;
	
	//	Get the filespec

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

	CString sFilespec(pStart, pPos - pStart);

	//	Get the directory

	CString sPackageFolder = fileGetPath(sFilespec);
	CString sPackageDescFilespec = fileGetFilename(sFilespec);

	//	Upload the package descriptor

	CString sPackageDesc = strPattern("/Arc.services/%s.ars", sPackageName);
	printf("Uploading %s to /Arc.services/%s.ars...", (LPSTR)sFilespec, (LPSTR)sPackageName);
	CString sResult = UploadFile(theSocket, CMD_UPLOAD, sPackageDesc, sFilespec);
	printf("%s\n", (LPSTR)sResult);

	//	Now loop over all files in the directory

	TArray<CString> Files;
	if (!fileGetFileList(fileAppend(sPackageFolder, CString("*.*")), 
			FFL_FLAG_RELATIVE_FILESPEC | FFL_FLAG_RECURSIVE,
			&Files))
		{
		printf("ERROR: Unable to list directory: %s\\*.*\n", (LPSTR)sPackageFolder);
		return NULL_STR;
		}

	for (i = 0; i < Files.GetCount(); i++)
		{
		if (!strEquals(Files[i], sPackageDescFilespec))
			{
			CString sFilePath = strPattern("/Arc.services/%s/%s", sPackageName, CAeonInterface::FilespecToFilePath(Files[i]));
			printf("Uploading %s to %s...", (LPSTR)fileAppend(sPackageFolder, Files[i]), (LPSTR)sFilePath);
			CString sResult = UploadFile(theSocket, CMD_UPLOAD, sFilePath, fileAppend(sPackageFolder, Files[i]));
			printf("%s\n", (LPSTR)sResult);
			}
		}

	//	Refresh

	printf("Refreshing Hyperion...");
	return ExecuteArcologyCommand(theSocket, CMD_REFRESH_PACKAGES);
	}
コード例 #15
0
ファイル: CDatum.cpp プロジェクト: gmoromisato/Hexarc
CDatum::Types CDatum::GetStringValueType (const CString &sValue)

//	GetStringValueType
//
//	Returns one of the following:
//
//	typeNil if sValue is empty
//	typeInteger32 if sValue is a 32-bit integer
//	typeIntegerIP if sValue is an integer (which may or may not be > 64-bits)
//	typeDouble if sValue is a double
//	typeString otherwise.

	{
	enum EStates
		{
		stateStart,
		stateHex0,
		stateHex,
		stateInteger,
		stateDoubleFrac,
		stateDoubleExp,
		stateDoubleExpSign,
		};

	char *pPos = sValue.GetParsePointer();
	char *pPosEnd = pPos + sValue.GetLength();
	int iState = stateStart;

	while (pPos < pPosEnd)
		{
		switch (iState)
			{
			case stateStart:
				{
				//	If 0 then we might be a hex number

				if (*pPos == '0')
					iState = stateHex0;

				//	If -, +, or a digit, we might be an integer

				else if (*pPos == '-' || *pPos == '+' || strIsDigit(pPos))
					iState = stateInteger;

				//	If . then we might be a double

				else if (*pPos == '.')
					iState = stateDoubleFrac;

				//	Otherwise, we are a string

				else
					return typeString;

				break;
				}

			case stateHex0:
				{
				if (*pPos == 'x' || *pPos == 'X')
					iState = stateHex;
				else if (strIsDigit(pPos))
					iState = stateInteger;
				else if (*pPos == '.')
					iState = stateDoubleFrac;
				else if (*pPos == 'e' || *pPos == 'E')
					iState = stateDoubleExp;
				else
					return typeString;

				break;
				}

			case stateHex:
				{
				if (strIsDigit(pPos)
						|| (*pPos >= 'A' && *pPos <= 'F')
						|| (*pPos >= 'a' && *pPos <= 'f'))
					NULL;
				else
					return typeString;

				break;
				}

			case stateInteger:
				{
				if (strIsDigit(pPos))
					NULL;
				else if (*pPos == '.')
					iState = stateDoubleFrac;
				else if (*pPos == 'e' || *pPos == 'E')
					iState = stateDoubleExp;
				else
					return typeString;

				break;
				}

			case stateDoubleFrac:
				{
				if (strIsDigit(pPos))
					NULL;
				else if (*pPos == 'e' || *pPos == 'E')
					iState = stateDoubleExp;
				else
					return typeString;

				break;
				}

			case stateDoubleExp:
				{
				if (*pPos == '+' || *pPos == '-' || strIsDigit(pPos))
					iState = stateDoubleExpSign;
				else
					return typeString;

				break;
				}

			case stateDoubleExpSign:
				{
				if (strIsDigit(pPos))
					NULL;
				else
					return typeString;

				break;
				}
			}

		pPos++;
		}

	switch (iState)
		{
		case stateStart:
			return typeNil;

		case stateHex:
			//	LATER:
			return typeString;

		case stateInteger:
			if (strOverflowsInteger32(sValue))
				return typeIntegerIP;
			else
				return typeInteger32;

		case stateDoubleFrac:
		case stateDoubleExpSign:
			return typeDouble;

		default:
			return typeString;
		}
	}
コード例 #16
0
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;
	}
コード例 #17
0
ファイル: HTML.cpp プロジェクト: gmoromisato/Hexarc
void htmlWriteAttributeValue (const CString &sText, IByteStream &Output)

//	htmlWriteAttributeValue
//
//	Writes attribute value text, escaping all appropriate characters.

	{
	char *pPos = sText.GetParsePointer();
	char *pPosEnd = pPos + sText.GetLength();

	char *pStart = pPos;

	while (pPos < pPosEnd)
		{
		if (*pPos == '<')
			{
			Output.Write(pStart, pPos - pStart);
			pPos++;
			pStart = pPos;

			Output.Write("&lt;", 4);
			}
		else if (*pPos == '>')
			{
			Output.Write(pStart, pPos - pStart);
			pPos++;
			pStart = pPos;

			Output.Write("&gt;", 4);
			}
		else if (*pPos == '&')
			{
			Output.Write(pStart, pPos - pStart);
			pPos++;
			pStart = pPos;

			Output.Write("&amp;", 5);
			}
		else if (*pPos == '\"')
			{
			Output.Write(pStart, pPos - pStart);
			pPos++;
			pStart = pPos;

			Output.Write("&quot;", 6);
			}
		else if (*pPos == '\'')
			{
			Output.Write(pStart, pPos - pStart);
			pPos++;
			pStart = pPos;

			Output.Write("&apos;", 6);
			}
		else if (*pPos == '`')
			{
			Output.Write(pStart, pPos - pStart);
			pPos++;
			pStart = pPos;

			Output.Write("&#096;", 6);
			}
		else
            //  LATER: Should check for lower-ASCII characters
			pPos++;
		}

	Output.Write(pStart, pPos - pStart);
	}
コード例 #18
0
ファイル: CArchonProcess.cpp プロジェクト: kronosaur/Hexarc
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;
	}
コード例 #19
0
ファイル: AI1.cpp プロジェクト: gmoromisato/Hexarc
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);
	}
コード例 #20
0
ファイル: CAeonInterface.cpp プロジェクト: kronosaur/Hexarc
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;
	}