📄 msgpartc.c
字号:
headBytes = 0; if ( headers != NULL ) { delete headers; headers = NULL; } char line[BUFLEN]; StringC headStr; char *getOK = fgets(line, BUFLEN-1, fp); Boolean done = strlen(line) <= 1; while ( getOK && !done ) { if ( debuglev > 2 ) cout <<"--> " <<line <<flush; headLines++; headBytes += strlen(line);//// Check for a continuation// if ( isspace(line[0]) ) headStr += line; else { if ( headStr.size() > 0 ) { // // KLUGE ALERT: remove spurrious ";;" in header, if any // int tmpSize = headStr.size(); headStr.Replace(";;",";"); headBytes -= headStr.size() - tmpSize; AddHeader(headStr); } headStr = line; } getOK = fgets(line, BUFLEN-1, fp); done = strlen(line) <= 1; } // End for each header line if ( debuglev > 2 && getOK ) cout <<"--> " <<line <<flush;//// See if we have a final header// if ( headStr.size() > 0 ) AddHeader(headStr);//// If this is an external part, look for another set of headers// if ( IsExternal() ) {//// Mark start of external headers// extOffset = (int)ftell(fp); extLines = 0; extBytes = 0; extBlank = 0; headStr.Clear();//// Look for more headers// getOK = fgets(line, BUFLEN-1, fp); done = strlen(line) <= 1; while ( getOK && !done ) { if ( debuglev > 2 ) cout <<"--> " <<line <<flush; extLines++; extBytes += strlen(line);//// Check for a continuation// if ( isspace(line[0]) ) headStr += line; else { if ( headStr.size() > 0 ) AddExtHeader(headStr); headStr = line; } getOK = fgets(line, BUFLEN-1, fp); done = strlen(line) <= 1; } // End for each header line if ( debuglev > 2 && getOK ) cout <<"--> " <<line <<flush; if ( getOK ) extBlank = 1; // Got blank line//// See if we have a final header// if ( headStr.size() > 0 ) AddExtHeader(headStr); } // End if part could have external headers//// Mark start of body// bodyOffset = (int)ftell(fp);//// See if we found a content-type header// defConType = (conStr.size() == 0); if ( defConType ) { if ( parent && parent->IsDigest() ) SetType("message/rfc822"); else SetType("text/plain"); }//// If this is an rfc822 part, look for a subject header// if ( Is822() ) { headStr.Clear();//// Look for more headers// getOK = fgets(line, BUFLEN-1, fp); done = strlen(line) <= 1; while ( getOK && !done ) {//// Check for a continuation// if ( isspace(line[0]) ) headStr += line; else { if ( headStr.size() > 0 && headStr.StartsWith("Subject:", IGNORE_CASE) ) SetSubject(headStr); headStr = line; } getOK = fgets(line, BUFLEN-1, fp); done = strlen(line) <= 1; } // End for each header line//// See if we have a final header// if ( headStr.StartsWith("Subject:", IGNORE_CASE) ) SetSubject(headStr);//// Move back to start of body// fseek(fp, bodyOffset, SEEK_SET); } // End if looking for subject header if ( closeFile ) fclose(fp); headScanned = True; return True;} // End ScanHead/*------------------------------------------------------------------------- * Add a header to the list */voidMsgPartC::AddHeader(CharC headStr){ HeaderC *newHead = new HeaderC(headStr);//// Add header at end of list// if ( !headers ) headers = newHead; else { HeaderC *last = headers; while ( last->next ) last = last->next; last->next = newHead; } CheckHead(newHead);} // End AddHeader/*------------------------------------------------------------------------- * Add an external header to the list */voidMsgPartC::AddExtHeader(CharC headStr){ HeaderC *newHead = new HeaderC(headStr);//// Add header at end of list// if ( !extHeaders ) extHeaders = newHead; else { HeaderC *last = extHeaders; while ( last->next ) last = last->next; last->next = newHead; } CheckHead(newHead);} // End AddExtHeader/*--------------------------------------------------------------- * Method to look at a header for special info */voidMsgPartC::CheckHead(HeaderC *head){ CharC key = head->key; if ( key.StartsWith("content-", IGNORE_CASE) ) key.CutBeg(strlen("content-")); StringC val; if ( key.Equals("type", IGNORE_CASE) ) { head->GetValueText(val); SetType(val); } else if ( key.Equals("disposition", IGNORE_CASE) ) { head->GetValueText(val); SetDisposition(val); } else if ( key.Equals("transfer-encoding", IGNORE_CASE) ) { head->GetValueText(val); SetEncoding(val); }} // End CheckHead/*--------------------------------------------------------------- * Method to set type */voidMsgPartC::SetType(CharC str){ conType = CT_UNKNOWN; grpType = GT_UNKNOWN; conStr.Clear(); grpStr.Clear(); subStr.Clear(); delete conParams; conParams = NULL;//// Separate parameters// CharC paramStr; int pos = str.PosOf(';'); if ( pos > 0 ) { conStr = str(0,pos); conStr.Trim(); paramStr = str(pos+1, str.Length()); paramStr.Trim(); } else conStr = str; conStr.toLower();//// Build list of parameters// if ( paramStr.Length() > 0 ) conParams = new ParamC(paramStr);//// Separate group and subtype// pos = conStr.PosOf('/'); if ( pos > 0 ) { grpStr = conStr(0, pos); subStr = conStr(pos+1, conStr.size()); } else grpStr = conStr; conType = ContentType(conStr); grpType = GroupType(grpStr);//// If external message, look for access type// if ( conType == CT_EXTERNAL ) { // Can't use IsExternal() yet ParamC *ap = Param(ACCESS_TYPE_S); if ( ap ) accType = AccessType(ap->val); else accType = AT_LOCAL_FILE; delete accParams; accParams = conParams; conParams = NULL; conType = CT_UNKNOWN; grpType = GT_UNKNOWN; conStr.Clear(); grpStr.Clear(); subStr.Clear();//// Point to the local file if necessary// if ( IsLocal() ) GetFileName(dataFile); } // End if external message} // End SetType/*--------------------------------------------------------------- * Method to set disposition */voidMsgPartC::SetDisposition(CharC str){//// Separate parameters// delete disParams; disParams = NULL; CharC paramStr; CharC dispStr; int pos = str.PosOf(';'); if ( pos > 0 ) { dispStr = str(0, pos); dispStr.Trim(); paramStr = str(pos+1, str.Length()); paramStr.Trim(); } else { dispStr = str; }//// Build list of parameters// if ( paramStr.Length() > 0 ) disParams = new ParamC(paramStr);} // End SetDisposition/*--------------------------------------------------------------- * Method to set encoding */voidMsgPartC::SetEncoding(CharC str){ encType = EncodingType(str);}/*--------------------------------------------------------------- * Method to set subject */voidMsgPartC::SetSubject(CharC str){ if ( subject ) delete subject; subject = new HeaderC(str);}/*--------------------------------------------------------------- * Method to scan this part from the offset to the next terminating line * or EOF */BooleanMsgPartC::Scan(FILE *fp, int maxBytes, TermFn *terminatingLine, char *nextBound, Boolean *gotLastBound, Boolean *prevLineBlank){ if ( bodyScanned ) return True; Boolean closeFile = (fp == NULL); if ( !fp ) { fp = fopen(msgFile, "r"); if ( !fp ) { StringC errmsg("Could not open file: \""); errmsg += msgFile; errmsg += "\".\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); return False; } }//// Scan the part headers// if ( !ScanHead(fp) ) return False;//// Get the boundary// StringC boundStr; if ( IsMultipart() ) { ParamC *curBound = Param(BOUNDARY_S); if ( !curBound ) { StringC errmsg("Malformed MIME message.\n"); errmsg += "Missing boundary parameter"; HeaderC *head = Header("Content-Description"); if ( head ) { errmsg += " for part\n"; head->GetValueText(errmsg); } halApp->PopupMessage(errmsg); SetType("text/plain"); } boundStr = "--"; if (curBound) boundStr += curBound->val; if ( debuglev > 2 ) cout <<"Multipart with boundary: " <<boundStr <<endl; } // End if this is a multipart//// Loop until we hit the max byte count or a terminating line. Only check// for a terminating line if maxBytes < 0// fseek(fp, bodyOffset, SEEK_SET); bodyLines = 0; bodyBytes = 0; if ( gotLastBound ) *gotLastBound = False; char line[BUFLEN]; CharC lineStr; Boolean gotBound = False; Boolean prevBlank = True; // line between headers and body Boolean checkBlank = True; Boolean done = False; char *getOK = fgets(line, BUFLEN-1, fp); while ( getOK && !done ) { if ( debuglev > 2 ) cout <<"--> " <<line <<flush; lineStr = line;//// Check for the end of this part// if ( nextBound ) { if ( lineStr.StartsWith(nextBound) ) { lineStr.CutBeg(strlen(nextBound)); if ( lineStr == "--\n" ) { lineStr.CutBeg(2); if ( gotLastBound ) *gotLastBound = True; } if ( lineStr == "\n" ) done = True; else lineStr = line;//// If we got a boundary, account for the fact the the newline we counted for// the previous line was really part of this boundary.// if ( done ) { gotBound = True; if ( bodyBytes > 0 ) bodyBytes--; else if ( extBlank > 0 ) extBlank--; // Lost blank line // after external head if ( prevBlank && bodyLines > 0 ) bodyLines--; } // End if we found the right boundary else if ( maxBytes >= 0 ) done = (bodyBytes >= maxBytes); } // End if got a boundary } // End if looking for a boundary else if ( maxBytes >= 0 ) done = (bodyBytes >= maxBytes); else if ( parentMsg && terminatingLine ) { long oldPos = ftell(fp); done = (*terminatingLine)(parentMsg, line, prevBlank); if ( done ) fseek(fp, oldPos, SEEK_SET); } if ( done ) continue;//// Add this line to the total// bodyLines++; bodyBytes += lineStr.Length();//// See if we're looking for the first boundary// if ( boundStr.size() > 0 ) { if ( lineStr.StartsWith(boundStr) ) { lineStr.CutBeg(boundStr.size()); if ( lineStr == "\n" ) {//// Add children until the last boundary is read// MsgPartC *newPart; MsgPartC *prev = NULL; Boolean gotLast = False; while ( !gotLast ) {//// Scan new part// newPart = new MsgPartC(this); newPart->offset = (int)ftell(fp); newPart->msgFile = msgFile; newPart->parentMsg = parentMsg; if ( !newPart->Scan(fp, maxBytes - bodyBytes, terminatingLine, boundStr, &gotLast, &prevBlank) ) return False; checkBlank = False; // Since we didn't read it here//// Add in child sizes// bodyLines += newPart->lines; bodyBytes += newPart->bytes;//// Add in the size of the boundary that ended the child// bodyLines++; bodyBytes += boundStr.size() + 2/*nl's before and after*/;//// Add in the dashes if this was the last boundary// if ( gotLast ) bodyBytes += 2;//// If the previous line was blank, count it here.// if ( prevBlank ) bodyLines++;//// Link in new part// if ( !child ) { child = newPart; } else if ( prev ) { prev->next = newPart; newPart->prev = prev; } prev = newPart; } // End while not last boundary } // End if found first boundary else if ( lineStr == "--\n" ) { // No children??? if ( gotLastBound ) *gotLastBound = True; } } // End if found a boundary } // End if looking for first boundary if ( checkBlank ) prevBlank = (strlen(line) <= 1); getOK = fgets(line, BUFLEN-1, fp); checkBlank = True; } // End for each line bodyScanned = True; if ( closeFile ) fclose(fp); if ( prevLineBlank ) *prevLineBlank = prevBlank;//// See if we left a multipart hanging// if ( nextBound && !gotBound ) { StringC errmsg("Malformed MIME message"); if ( parentMsg ) { errmsg += ' '; errmsg += parentMsg->Number(); } errmsg += ".\nCannot find closing boundary:\n"; errmsg += nextBound; errmsg += "--";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -