void
GMMIMEParser::ParseQuotedPrintable
	(
	JString* text
	)
{
	// read until '='
	// if next two characters are hex, then decode and replace
	// if next char is whitespace, then toss  = --> '\n'
	// if neither of the above, just toss the '=', this is an error

	JIndex findex	= 1;
	while (text->LocateNextSubstring("=", &findex))
		{
		JSize size	= text->GetLength();
		if (findex < size)
			{
			JCharacter c	= text->GetCharacter(findex + 1);
			if (isspace(c) || (c == '\n'))
				{
				JIndex rIndex	= findex;
				if (text->LocateNextSubstring("\n", &rIndex))
					{
					text->RemoveSubstring(findex, rIndex);
					}
				else
					{
					text->RemoveSubstring(findex, text->GetLength());
					}
				}
			else if (findex < size - 1)
				{
				JString hex	= text->GetSubstring(findex + 1, findex + 2);
				hex.Prepend("0x");
				JInteger hexVal;
				if (hex.ConvertToInteger(&hexVal))
					{
					text->RemoveSubstring(findex, findex + 2);
					c	= (JCharacter)hexVal;
					text->InsertCharacter(c, findex);
					findex++;
					}
				else
					{
					text->RemoveSubstring(findex, findex);
					}
				}
			else
				{
				text->RemoveSubstring(findex, text->GetLength());
				}
			}
		else
			{
			text->RemoveSubstring(findex, findex);
			}
		}
}
JString
GMessageHeader::DecodeMIMEWord
	(
	const JBoolean		qType,
	JString*			header,
	const JIndexRange	range
	)
{
	JString temp;
	JIndex findex	= range.first;
	// first ? '=?'
	JBoolean ok		= header->LocateNextSubstring("?", &findex);
	if (!ok)
		{
		return temp;
		}
	findex++;
	// second ? '?Q'
	ok		= header->LocateNextSubstring("?", &findex);
	if (!ok)
		{
		return temp;
		}
	// third ? 'Q?'
	findex++;
	ok		= header->LocateNextSubstring("?", &findex);
	if (!ok || (findex > range.last))
		{
		return temp;
		}
	JIndex endIndex	= findex + 1;
	// final ? '?='
	ok		= header->LocateNextSubstring("?", &endIndex);
	if (!ok || (endIndex > range.last))
		{
		return temp;
		}
	// so the encoded text is between findex and endIndex.
	if (qType)
		{
		JIndex dIndex	= findex + 1;
		while (dIndex < endIndex)
			{
			JCharacter c	= header->GetCharacter(dIndex);
			if (c == '=')
				{
				JString hex	= header->GetSubstring(dIndex + 1, dIndex + 2);
				hex.Prepend("0x");
				JInteger hexVal;
				if (hex.ConvertToInteger(&hexVal))
					{
					c	= (JCharacter)hexVal;
					temp.AppendCharacter(c);
					dIndex += 3;
					}
				}
			else if (c == '_')
				{
				temp.AppendCharacter(' ');
				dIndex++;
				}
			else
				{
				temp.AppendCharacter(c);
				dIndex++;
				}
			}
		}
	else
		{
		if (findex + 1 > header->GetLength())
			{
			return temp;
			}
		if (endIndex - 1 < findex + 1)
			{
			return temp;
			}
		temp = header->GetSubstring(findex + 1, endIndex - 1);
		const std::string s(temp.GetCString(), temp.GetLength());
		std::istringstream is(s);
		std::ostringstream os;
		JDecodeBase64(is, os);
		temp = os.str();
		}
	return temp;
}
예제 #3
0
void
SMTPMessage::ReadReturnValue()
{
	JString line;
	JBoolean ok = itsLink->GetNextMessage(&line);
	assert(ok);

	if (itsCurrentMode != kDataHeader)
		{
		GMGetSMTPDebugDir()->AddText(line);
		}

	if ((itsCurrentMode != kStartUp) && (itsCurrentMode != kDataHeader))
		{
		JInteger value;
		JIndex findex;
		ok = line.LocateSubstring(" ", &findex);
		if (ok && (findex > 1))
			{
			JString number = line.GetSubstring(1, findex - 1);
			if (number.IsInteger())
				{
				number.ConvertToInteger(&value);
				}
			else
				{
				ok	= kJFalse;
				}
			}
		else
			{
			ok	= kJFalse;
			}

		if (!ok)
			{
			const JIndex kDashIndex	= 4;
			if (line.GetCharacter(kDashIndex) == '-')
				{
				// this is a multiline response.
				return;
				}
			}

		if (!ok || (value != kOKValue))
			{
			if (!itsIsTryingToQuit)
				{
				const JCharacter* map[] =
					{
					"err", line
					};
				const JString msg = JGetString("SMTPERROR", map, sizeof(map));

				JGetUserNotification()->ReportError(msg);
				}
			itsIsFinished = kJTrue;
			Broadcast(SendFailure());
			if (!itsIsTryingToQuit)
				{
				itsDeleteTask = new JXTimerTask(1000,kJTrue);
				assert( itsDeleteTask != NULL );
				itsDeleteTask->Start();
				ListenTo(itsDeleteTask);
				}
			return;
			}
		}

	if (itsCurrentMode < kTo)
		{
		itsCurrentMode++;
		}
	else if (itsCurrentMode == kTo)
		{
		if (itsCurrentIndex < itsToNames->GetElementCount())
			{
			itsCurrentIndex++;
			}
		else if (itsCcNames->GetElementCount() != 0)
			{
			itsCurrentMode = kCc;
			itsCurrentIndex = 1;
			}
		else if (itsBccNames->GetElementCount() != 0)
			{
			itsCurrentMode = kBcc;
			itsCurrentIndex = 1;
			}
		else
			{
			itsCurrentMode = kDataHeader;
			}
		}
	else if (itsCurrentMode == kCc)
		{
		if (itsCurrentIndex < itsCcNames->GetElementCount())
			{
			itsCurrentIndex++;
			}
		else if (itsBccNames->GetElementCount() != 0)
			{
			itsCurrentMode = kBcc;
			itsCurrentIndex = 1;
			}
		else
			{
			itsCurrentMode = kDataHeader;
			}
		}
	else if (itsCurrentMode == kBcc)
		{
		if (itsCurrentIndex < itsBccNames->GetElementCount())
			{
			itsCurrentIndex++;
			}
		else
			{
			itsCurrentMode = kDataHeader;
			}
		}
	else if (itsCurrentMode == kData)
		{
		itsIsFinished = kJTrue;
		Broadcast(MessageSent());
		GMGetSMTPDebugDir()->AddText("\n-------------------------------------\n");
		if (!itsIsTryingToQuit)
			{
			itsDeleteTask = new JXTimerTask(1000,kJTrue);
			assert( itsDeleteTask != NULL );
			itsDeleteTask->Start();
			ListenTo(itsDeleteTask);
			}
		return;
		}
	else
		{
		itsCurrentMode++;
		}

	SendNextData();
}