int MailMessage::parseHeaders(StringBuffer &rfcHeaders) { ArrayList lines; const StringBuffer *line; StringBuffer strReceived; bool receivedExtracted = false; LOG.debug("parseHeaders START"); // Join header parts using \t or 8 blank StringBuffer joinlinetab("\t"); rfcHeaders.replaceAll(joinlinetab, " "); StringBuffer joinlinespaces(newline); joinlinespaces+=" "; // 8 blanks rfcHeaders.replaceAll(joinlinespaces, " "); rfcHeaders.split(lines, newline); // importance is set to "0" by default. Then there isn't anything modification // in the header, at the end of the loop the importance will be set to "3", default normal importance = "0"; for ( line=(StringBuffer *)lines.front(); line; line=(StringBuffer *)lines.next() ) { if( *line == "\r" ) break; // The first empty line marks the end of the header section if( line->empty() ){ break; } // Process the headers if( line->ifind(TO) == 0 ){ to = MailMessage::decodeHeader(line->substr(TO_LEN)); } else if( line->ifind(FROM) == 0 ) { from = MailMessage::decodeHeader(line->substr(FROM_LEN)); } else if( line->ifind(CC) == 0 ) { cc = MailMessage::decodeHeader(line->substr(CC_LEN)); } else if( line->ifind(BCC) == 0 ) { bcc = MailMessage::decodeHeader(line->substr(BCC_LEN)); } else if ( line->ifind(DATE) == 0 ) { //subjectParsing = false; if( date.parseRfc822(line->substr(DATE_LEN)) ) { LOG.error("Error parsing date"); return 500; } } else if( line->ifind(SUBJECT) == 0 ) { subject = MailMessage::decodeHeader(line->substr(SUBJECT_LEN)); LOG.debug("SUBJECT: %s", subject.c_str()); } else if( line->ifind(ENCODING) == 0 ) { // it is here for single part only body.setEncoding(line->substr(ENCODING_LEN)); } else if(line->ifind(MIMEVERS) == 0 ) { mimeVersion = line->substr(MIMEVERS_LEN); } else if(line->ifind(MESSAGEID) == 0 ) { messageId = line->substr(MESSAGEID_LEN); } else if(line->ifind(IMPORTANCE) == 0 ) { StringBuffer data = line->substr(IMPORTANCE_LEN); data.lowerCase(); importance = convertImportance(data); } else if(line->ifind(X_PRIORITY) == 0 ) { if (importance == "0") { StringBuffer data = line->substr(X_PRIORITY_LEN); data.lowerCase(); importance = convertXPriority(data); } } else if( line->ifind(MIMETYPE) == 0 ) { StringBuffer sb = getTokenValue(line, MIMETYPE); if (sb.length() > 0) contentType = sb; sb.reset(); sb = getTokenValue(line, "boundary=", false); if (sb.length() > 0) { boundary = sb; } else { body.setCharset(getTokenValue(line, CT_CHARSET)); } /* size_t len = line->find(";") - MIMETYPE_LEN ; contentType = line->substr(MIMETYPE_LEN, len); // Save boundary for multipart size_t begin = line->ifind("boundary="); size_t end = StringBuffer::npos; if( begin != StringBuffer::npos ) { begin += strlen("boundary=\""); end = line->find("\"", begin) ; boundary = line->substr( begin, end-begin ); } else { begin=line->ifind(CT_CHARSET); if( begin != StringBuffer::npos ) { begin += strlen(CT_CHARSET); size_t end = begin; size_t quote = line->find("\"", begin); if (quote != StringBuffer::npos){ begin = quote + 1; end = line->find("\"", begin) ; } else { end = line->find(";", begin) ; if (end == StringBuffer::npos) { end = line->find(" ", begin); } } body.setCharset( line->substr( begin, end-begin ) ); } } */ } else if(line->ifind(RECEIVED) == 0) { if (!receivedExtracted) { strReceived = line->substr(line->rfind(";") ); if (!strReceived.empty()) { received.parseRfc822(strReceived.substr(2)); receivedExtracted = true; } /* while (!strReceived.empty()) { if (received.parseRfc822(strReceived.substr(2)) == 0) { receivedExtracted = true; break; } else { StringBuffer s(line->substr(line->rfind(strReceived.c_str()))); strReceived = line->substr(s.rfind(";")); } } */ } } else { headers.add(*(StringBuffer *)line); } } // If received was not found, copy send date if( received == BasicTime() ){ received = date; } // if the importance is never set we put the importance to 3, normal if (importance == "0") { importance = "3"; } LOG.debug("parseHeaders END"); // FIXME: should check for mandatory headers before return 0 return 0; }
// Return true if the instance is empty (a valid MailMessage must have a valid date that is not // the default 1/1/1970) bool MailMessage::empty() { return ( this->getDate() == BasicTime() ); }
/** * Parse the date in RF 822 format * * Some examples: * Date: Fri, 01 Aug 2003 14:04:55 +0800 * Date: Wed, 30 Jul 2003 13:24:21 -0700 * Date: 20 Jun 2003 15:42:12 -0500 * * RFC822 date time * * date-time = [ day "," ] date time ; dd mm yy * ; hh:mm:ss zzz * * day = "Mon" / "Tue" / "Wed" / "Thu" * / "Fri" / "Sat" / "Sun" * * date = 1*2DIGIT month 2DIGIT ; day month year * ; e.g. 20 Jun 82 * * month = "Jan" / "Feb" / "Mar" / "Apr" * / "May" / "Jun" / "Jul" / "Aug" * / "Sep" / "Oct" / "Nov" / "Dec" * * time = hour zone ; ANSI and Military * * hour = 2DIGIT ":" 2DIGIT [":" 2DIGIT] * ; 00:00:00 - 23:59:59 * * zone = "UT" / "GMT" ; Universal Time * ; North American : UT * / "EST" / "EDT" ; Eastern: - 5/ - 4 * / "CST" / "CDT" ; Central: - 6/ - 5 * / "MST" / "MDT" ; Mountain: - 7/ - 6 * / "PST" / "PDT" ; Pacific: - 8/ - 7 * / 1ALPHA ; Military: Z = UT; * ; A:-1; (J not used) * ; M:-12; N:+1; Y:+12 * / ( ("+" / "-") 4DIGIT ) ; Local differential * ; hours+min. (HHMM) **/ int BasicTime::parseRfc822(const char *date) { int ret = 0; if (!isADate(date)) { return -1; } const char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; // In some cases the day of week may initially contain the day,dayofmonth, // so its max length is 3+1+2 char dayOfWeek[7] = "---,"; char mon[4] = "---"; char time[10] = "00:00:00"; char timeZone[20] = "GMT"; // Wed Feb 01 14:40:45 Europe/Amsterdam 2006 // do we have day of week? const char *pdate = strstr( date, "," ); if ( pdate == 0 ) { ret=sscanf(date, "%d %s %d %s %s", &day, mon, &year, time, timeZone); } else { ret=sscanf(date, "%s %d %s %d %s %s", dayOfWeek, &day, mon, &year, time, timeZone); if (ret >= 1 && ret < 6) { // it can be an error in the format: Mon,12 Feb 2007 09:00:01 +0100 // the comma is attached to the day if (*(pdate + 1) != ' ') { ret = sscanf(pdate + 1, "%d %s %d %s %s", &day, mon, &year, time, timeZone); } } // Convert day of week for (int i = 0; i < 7; i++) { if ( strncmp(days[i], dayOfWeek, 3) == 0 ) { weekday = i; break; } } // Do not exit on error on weekday, treat it like if it was // not present. } // Trap parsing error if(ret == EOF || ret == 0){ return -1; } // Check validity if (year > 3000 || day < 0 || day > 31){ *this = BasicTime(); return -1; } // Get month int i; for (i = 0; i < 12; i++) { if ( strcmp(months[i], mon) == 0 ) { month = i+1; break; } } // Trap parsing error if (i==13) { return -1; } // Year --------------------------------- if (year <= 60) { year += 2000; } else if (year > 60 && year < 100) { year += 1900; } // hh:mm:ss ------------------------- // do we have sec? if (strlen(time) > 6 && time[5] == ':') sscanf(time, "%d:%d:%d", &hour, &min, &sec); else sscanf(time, "%d:%d", &hour, &min); // Timezone --------------------------------- if ( strcmp(timeZone, "GMT") != 0 && strcmp(timeZone, "UT") != 0) { // is this explicit time? if ( timeZone[0] == '+' || timeZone[0]== '-' ) { char wcH[4] = "+00"; char wcM[4] = "00"; // get hour if ( strlen(timeZone) > 3) { wcH[0] = timeZone[0]; wcH[1] = timeZone[1]; wcH[2] = timeZone[2]; wcH[3] = '\0'; } // get min if ( strlen(timeZone) >= 5) { wcM[0] = timeZone[3]; wcM[1] = timeZone[4]; wcM[2] = '\0'; } tzHour = atoi(wcH); tzMin = atoi(wcM); } // otherwise it could be one string with the time else if ( strcmp(timeZone, "EDT") == 0) { tzHour = -4; } else if ( strcmp(timeZone, "EST") == 0 || strcmp(timeZone, "CDT") == 0) { tzHour = -5; } else if ( strcmp(timeZone, "CST") == 0 || strcmp(timeZone, "MDT") == 0) { tzHour = -6; } else if ( strcmp(timeZone, "MST") == 0 || strcmp(timeZone, "PDT") == 0 ){ tzHour = -7; } else if ( strcmp(timeZone, "PST") == 0) { tzHour = -8; } } // clean up return 0; }