|
|
|
|
|
|
|
|
|
|
|
|
|
|
//// Version Info |
|
|
//// Version Info |
|
|
|
|
|
|
|
|
const char* SNF_ENGINE_VERSION = "SNFMulti Engine Version 3.0.12 Build: " __DATE__ " " __TIME__; |
|
|
|
|
|
|
|
|
const char* SNF_ENGINE_VERSION = "SNFMulti Engine Version 3.0.13 Build: " __DATE__ " " __TIME__; |
|
|
|
|
|
|
|
|
//// Script Caller Methods |
|
|
//// Script Caller Methods |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// The insertion point will be at the end of the existing headers. |
|
|
// The insertion point will be at the end of the existing headers. |
|
|
// We pick that point to be right between the two <cr><lf> so that |
|
|
// We pick that point to be right between the two <cr><lf> so that |
|
|
// the first blank line will appear at the end of our headers. |
|
|
// the first blank line will appear at the end of our headers. |
|
|
// We also try to accommodate some cases where the message may |
|
|
|
|
|
// have been rewritten incorrectly or translated so that instead |
|
|
|
|
|
// of <cr><lf><cr><lf> we find <lf><lf> -- this might happen on some |
|
|
|
|
|
// *nix like systems if the software and/or scripting involved isn't |
|
|
|
|
|
// quite up to spec. We are reading a file, after all. |
|
|
|
|
|
|
|
|
|
|
|
unsigned int ipt = 0; // Insert search point. |
|
|
|
|
|
|
|
|
|
|
|
if(MessageBuffer.size() != MyScanData.ScanSize) { // If our scanner skipped data at |
|
|
|
|
|
ipt = MessageBuffer.size() - MyScanData.ScanSize; // the top of the message buffer then |
|
|
|
|
|
} // we will skip it too. |
|
|
|
|
|
|
|
|
|
|
|
int InsertPoint = 0; // Find the insertion point. |
|
|
|
|
|
bool UseLFOnly = false; // Patchup line ends for *nix files? |
|
|
|
|
|
bool CRLFPresent = false; // Detected \r\n pairs? |
|
|
|
|
|
for(; ipt<(MessageBuffer.size()-4); ipt++) { // Search for the first blank line. |
|
|
|
|
|
|
|
|
|
|
|
if( // Detect CRLF pairs if present. |
|
|
|
|
|
false == CRLFPresent && |
|
|
|
|
|
'\r' == MessageBuffer.at(ipt) && |
|
|
|
|
|
'\n' == MessageBuffer.at(ipt + 1) |
|
|
|
|
|
) CRLFPresent = true; |
|
|
|
|
|
|
|
|
|
|
|
if( // In a properly formatted RFC822 |
|
|
|
|
|
'\r' == MessageBuffer.at(ipt) && // message that looks like |
|
|
|
|
|
'\n' == MessageBuffer.at(ipt + 1) && // <cr><lf><cr><lf> |
|
|
|
|
|
'\r' == MessageBuffer.at(ipt + 2) && |
|
|
|
|
|
'\n' == MessageBuffer.at(ipt + 3) |
|
|
|
|
|
) { |
|
|
|
|
|
InsertPoint = ipt + 2; |
|
|
|
|
|
break; |
|
|
|
|
|
} else |
|
|
|
|
|
if( // In some bizarre cases it might |
|
|
|
|
|
'\n' == MessageBuffer.at(ipt) && // look like <lf><lf>. |
|
|
|
|
|
'\n' == MessageBuffer.at(ipt + 1) |
|
|
|
|
|
) { |
|
|
|
|
|
InsertPoint = ipt + 1; |
|
|
|
|
|
UseLFOnly = true; // We have to strip <CR> from our |
|
|
|
|
|
break; // injected header line ends. |
|
|
|
|
|
|
|
|
// We accommodate either <cr><lf> or <lf> line endings.
|
|
|
|
|
|
// We are careful not to search past the end of unreasonably short
|
|
|
|
|
|
// message files.
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int InsertPoint = 0; // Find the insertion point. |
|
|
|
|
|
bool UseLFOnly = false; // Use \n line endings in files? |
|
|
|
|
|
bool CRLFPresent = false; // Detected \r\n pairs?
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int BiggestPatternSize = 4; // How far we look ahead.
|
|
|
|
|
|
bool BigEnoughMessage = BiggestPatternSize < MessageBuffer.size();
|
|
|
|
|
|
|
|
|
|
|
|
if(BigEnoughMessage){
|
|
|
|
|
|
unsigned int Limit = MessageBuffer.size() - BiggestPatternSize;
|
|
|
|
|
|
bool DataWasSkipped = MessageBuffer.size() > MyScanData.ScanSize;
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int i = 0;
|
|
|
|
|
|
if(DataWasSkipped) { // If our scanner skipped data at
|
|
|
|
|
|
i = MessageBuffer.size() - MyScanData.ScanSize; // the top of the message buffer then
|
|
|
|
|
|
} // we will skip it too.
|
|
|
|
|
|
|
|
|
|
|
|
for(; i < Limit; i++) { // Search for the first blank line. |
|
|
|
|
|
|
|
|
|
|
|
if( // Detect CRLF pairs if present. |
|
|
|
|
|
false == CRLFPresent && |
|
|
|
|
|
'\r' == MessageBuffer.at(i) && |
|
|
|
|
|
'\n' == MessageBuffer.at(i + 1) |
|
|
|
|
|
) CRLFPresent = true; |
|
|
|
|
|
|
|
|
|
|
|
if( // In a properly formatted RFC822 |
|
|
|
|
|
'\r' == MessageBuffer.at(i) && // message that looks like |
|
|
|
|
|
'\n' == MessageBuffer.at(i + 1) && // <cr><lf><cr><lf> |
|
|
|
|
|
'\r' == MessageBuffer.at(i + 2) && |
|
|
|
|
|
'\n' == MessageBuffer.at(i + 3) |
|
|
|
|
|
) { |
|
|
|
|
|
InsertPoint = i + 2; |
|
|
|
|
|
break; |
|
|
|
|
|
} else |
|
|
|
|
|
if( // In some bizarre cases it might |
|
|
|
|
|
'\n' == MessageBuffer.at(i) && // look like <lf><lf>. |
|
|
|
|
|
'\n' == MessageBuffer.at(i + 1) |
|
|
|
|
|
) { |
|
|
|
|
|
InsertPoint = i + 1; |
|
|
|
|
|
UseLFOnly = true; // We have to strip <CR> from our |
|
|
|
|
|
break; // injected header line ends. |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
// Here we must interpret the results of our scan. Do we know where |
|
|
|
|
|
|
|
|
// Here we must interpret the results of our search. Do we know where |
|
|
// our insert point is or do we punt and use the top of the message? |
|
|
// our insert point is or do we punt and use the top of the message? |
|
|
|
|
|
|
|
|
if(0 == InsertPoint) { // No blank line? We need to punt. |
|
|
if(0 == InsertPoint) { // No blank line? We need to punt. |