/** * Get the next bodypart from the message body string. * * @param rfcBody (in) - message content * @param boundary (in) - mime boundary string * @param ret (out) - parsed BodyPart * @param next (i/o) - offset of the new boundary * @param isAttach (in) - says if the current body part is an attachment or not */ static bool getBodyPart(StringBuffer &rfcBody, StringBuffer &boundary, BodyPart &ret, size_t &next, bool isAttach) { LOG.debug("getBodyPart START"); StringBuffer newline; // The part starts on the next line size_t begin = findNewLine(rfcBody, next); if (begin == StringBuffer::npos) return false; // find the end of the part next = rfcBody.find(boundary, begin); if (next == StringBuffer::npos) return false; // get the part StringBuffer part = rfcBody.substr(begin, next-begin); // If it is a multipart alternative part, get the text part only. // check only until the first new line not on all the message (it could be // a message inside another message) size_t headers_len = getHeadersLen(part, newline); StringBuffer headers_part = part.substr(0, headers_len); if (headers_part.ifind("Content-Type: multipart/alternative") != StringBuffer::npos) { if(part.ifind("Content-Type: multipart/alternative") != StringBuffer::npos) { size_t b_pos = part.ifind("boundary="); if( b_pos != StringBuffer::npos ) { size_t begin = part.find("=\"", b_pos) + 2 ; size_t end = part.find("\"", begin) ; StringBuffer inner_boundary("\n--"); inner_boundary += part.substr( begin, end-begin ); begin = part.find(inner_boundary, end); begin += inner_boundary.length(); end = part.find(inner_boundary, begin); if (begin != StringBuffer::npos && end != StringBuffer::npos) { part = part.substr(begin, end-begin); LOG.debug("Bodypart is multipart/alternative: " "getting first alternative only: \n%s\n", part.c_str() ); } } } } // Split headers and body size_t hdrlen = getHeadersLen(part, newline); // Get headers StringBuffer headers = part.substr(0, hdrlen); // Join header parts using \t or 8 blank StringBuffer joinlinetab("\t"); headers.replaceAll(joinlinetab, " "); StringBuffer joinlinespaces(newline); joinlinespaces+=" "; // 8 blanks headers.replaceAll(joinlinespaces, " "); ArrayList lines; const StringBuffer *line; // parse the bodypart headers headers.split(lines, newline); for ( line=(StringBuffer *)lines.front(); line; line=(StringBuffer *)lines.next() ) { if( *line == "\r" ) continue; // The first empty line marks the end of the header section //if( line->empty() ){ // break; //} // Process the headers if( line->ifind(MIMETYPE) == 0 ) { // it must at the beginning ret.setMimeType(getTokenValue(line, MIMETYPE)); if (line->ifind(CT_NAME) != StringBuffer::npos) { ret.setName(MailMessage::decodeHeader(getTokenValue(line, CT_NAME,false))); } if (line->ifind(CT_CHARSET) != StringBuffer::npos ) { ret.setCharset(getTokenValue(line, CT_CHARSET)); } } else if( line->ifind(DISPOSITION) == 0 ) { ret.setDisposition( getTokenValue(line, DISPOSITION)); if (line->ifind(CD_FILENAME) != StringBuffer::npos ) { ret.setFilename( MailMessage::decodeHeader( getTokenValue(line, CD_FILENAME, false) ) ); } } else if( line->ifind(ENCODING) == 0 ) { ret.setEncoding( getTokenValue(line, ENCODING)); } } // move to the beginning of the content hdrlen += strlen(newline) + strlen(newline); // added 2 new line that separate the bodyparts // get bodypart content if( isAttach == false) { // || !ret.getFilename() ) { // this is not an attachment if(ret.getEncoding() && strcmp(ret.getEncoding(), "quoted-printable") == 0 ) { char *decoded = qp_decode( part.substr(hdrlen) ); ret.setContent ( decoded ); delete [] decoded; } else if (ret.getEncoding() && strcmp(ret.getEncoding(), "base64") == 0 ) { char *decoded = ""; size_t len = 0; if( uudecode( part.substr(hdrlen), &decoded, &len ) ) { LOG.error("Error decoding content"); } ret.setContent ( decoded ); delete [] decoded; } else { bool found = true; if (part.substr(hdrlen).length() < 6) { StringBuffer s(part.substr(hdrlen)); for (unsigned int i = 0; i < s.length(); i++) { if (s.c_str()[i] != '\r' && s.c_str()[i] != '\n') { found = true; break; } else { found = false; } } } if (found) { ret.setContent ( part.substr(hdrlen) ); } } } else { LOG.debug("Attachment"); ret.setContent( mkTempFileName( ret.getFilename() ) ); LOG.debug("%s", ret.getContent()); StringBuffer p = part.substr(hdrlen); if (p.length()) { LOG.debug("Saving..."); if( convertAndSave(ret.getContent(), p.c_str(), ret.getEncoding()) ) { LOG.error("Error in convertAndSave"); } else { LOG.debug("convertAndSave success"); } } } LOG.debug("getBodyPart END"); // return true if there are more parts return (next != StringBuffer::npos); }
int main(int argc, char** argv) #endif { size_t msglen=0; WCHAR *name[10], *msg=0; int i; const WCHAR *attach; #ifdef _WIN32_WCE name[0] = stringdup(TEXT("message.xml")); name[1] = stringdup(TEXT("text.xml")); name[2] = NULL; attach = TEXT("/synclog.txt"); #else for(i=1; i<argc; i++) name[i-1] = utf82wc(argv[i]); name[i-1] = NULL; attach = TEXT("c:/windows/temp/synclog.txt"); #endif LOG.setLevel(LOG_LEVEL_DEBUG); // Force debug level for this test. // Test parse/format loop if names were given on cmdline for (i=0; name[i]; i++) { msg = loadAndConvert(name[i]); if( !msg ){ WCHAR dbg[256]; wsprintf(dbg, TEXT("Can't open file %s\n"), name[i]); LOG.error("%s", dbg); continue; } EmailData em; if (em.parse(msg)) fprintf(stderr, "Parse failed on: %S\n", name[i]); delete [] msg; WCHAR outname[10]; wsprintf(outname, TEXT("msgout%d.xml"), i); if ( convertAndSave( outname, em.format() ) ) { fprintf(stderr, "Error in convertAndSave(em)\n"); } } // Try to send a new mail with attachment EmailData newmail; MailMessage n; BodyPart body; body.setContent(TEXT("Ma che bella la città!")); n.setFrom(TEXT("*****@*****.**")); n.setTo(TEXT("*****@*****.**")); n.setSubject(TEXT("Test")); n.setBody(body); BodyPart a; a.setFilename( TEXT("pippo.txt") ); a.setContent( attach ); a.setEncoding( TEXT("base64") ); n.addAttachment(a); newmail.setRead(true); newmail.setEmailItem(n); if ( convertAndSave( L"attachment.xml", newmail.format() ) ) { fprintf(stderr, "Error in convertAndSave(newmail)\n"); } //extern size_t StringBuffer_memcount; //fprintf(stderr, "Memcount: %ld\n", StringBuffer_memcount); //getchar(); return 0; }