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; }
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(); }