📄 msgc.c
字号:
if ( valStr.Contains('<') ) { u_int loff = 0; int lpos = valStr.PosOf('<', loff); while ( lpos >= 0 ) { valStr(lpos,0) = "<"; loff = lpos + 2; lpos = valStr.PosOf('<', loff); } }//// Substitute value for %key// if ( valStr.length() == 0 ) valStr = "Unknown"; str(pos, key.Length()+1) = valStr; off = pos + valStr.length(); } else off = pos + 1; } // End if %header found } // End for each %} // End ReplaceHeaders/*--------------------------------------------------------------- * Method to scan the the headers from the offset to the next blank * or terminating line */voidMsgC::ScanHeadFile(FILE *fp){ if ( !body->ScanHead(fp) ) { return; } if ( debuglev > 1 ) { StringC tmp; GetSubjectText(tmp); cout <<"Found: " <<tmp <<endl; }//// Check for special headers// HeaderC *head = body->headers; while ( head ) { CheckHeader(head); head = head->next; } body->SetPartNumber("1");//// Don't mark plain text as MIME// if ( IsSet(MSG_MIME) && body->IsPlainText() && !body->IsEncoded() && !body->IsAttachment() && !body->IsExternal() ) ClearStatus(MSG_MIME); ClearStatus(MSG_CHANGED);} // End ScanHeadFile/*--------------------------------------------------------------- * The default terminating line function */static BooleanTerminatingLine(MsgC*, CharC, Boolean){ return False;}void*MsgC::TerminatingLineFn(){ return (void*)TerminatingLine;}/*--------------------------------------------------------------- * Method to scan the the body from the offset to the next terminating line * or EOF */voidMsgC::ScanBodyFile(FILE *fp){ if ( debuglev > 1 ) cout <<"Scanning body for message " <<number <<" at offset " <<body->bodyOffset <<endl; if ( !body->Scan(fp, body->bodyBytes, (TermFn*)TerminatingLineFn()) ) return;//// Assign default types to parts that have no type// body->SetPartNumber("1"); body->SetPartNumberSize(body->GetPartNumberMaxSize()); if ( debuglev > 1 ) cout <<"Found " <<body->bodyLines <<" lines" <<endl; bodySizeKnown = True;} // End ScanBodyFile/*--------------------------------------------------------------- * Method to return the header text */BooleanMsgC::ReadHeaderText(FILE *fp, StringC& text) const{ return body->GetText(text, fp, True, False, False, False);}/*--------------------------------------------------------------- * Method to return the body text */BooleanMsgC::ReadBodyText(FILE *fp, StringC& text) const{ return body->GetText(text, fp);}/*------------------------------------------------------------------------ * Method to write this message to the specified file */BooleanMsgC::WriteFile(const char *file, Boolean copyHead, Boolean allHead, Boolean statHead, Boolean addBlank, Boolean protectFroms){ FILE *fp; fp = fopen(file, "a"); if ( !fp ) { StringC errmsg("Could not open file: "); errmsg += file; errmsg += ".\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); return False; } Boolean success = WriteFile(fp, copyHead, allHead, statHead, addBlank, protectFroms); fclose(fp); return success;} // End WriteFile/*------------------------------------------------------------------------ * Method to write this message to an open file */BooleanMsgC::WriteFile(FILE *fp, Boolean copyHead, Boolean allHead, Boolean statHead, Boolean addBlank, Boolean protectFroms){ if ( copyHead && !WriteHeaders(fp, allHead, statHead) ) return False; if ( !WriteBody(fp, addBlank, protectFroms) ) return False; return True;}/*------------------------------------------------------------------------ * Method to write the headers to the specified file */BooleanMsgC::WriteHeaders(const char *file, Boolean allHead, Boolean statHead){ FILE *fp; fp = fopen(file, "a"); if ( !fp ) { StringC errmsg("Could not open file: "); errmsg += file; errmsg += ".\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); return False; } Boolean success = WriteHeaders(fp, allHead, statHead); fclose(fp); return success;} // End WriteHeaders/*------------------------------------------------------------------------ * Method to write the headers to an open file */BooleanMsgC::WriteHeaders(FILE *fp, Boolean allHead, Boolean statHead){ headWritePos = ftell(fp); Boolean someWritten = False; CharC nlStr("\n");//// Loop through headers// HeaderC *head = body->headers; while ( head ) {//// Write this header if necessary// Boolean writeIt = allHead || ishApp->headPrefs->HeaderShown(head->key); if ( writeIt ) {//// If this is the Content-Length header, make sure it is correct// if ( head->key.Equals("content-length", IGNORE_CASE) ) { StringC lenStr; head->GetValueText(lenStr); lenStr.Trim(); int len = atoi(lenStr); if ( len != BodyBytes() ) { if ( debuglev > 0 ) { cout <<"Fixing Content-Length header for message " <<number; cout <<"." <<endl; cout <<"Was " <<len <<", should be " <<BodyBytes() <<endl; } lenStr = "Content-Length: "; lenStr += (int)BodyBytes(); if ( !lenStr.WriteFile(fp) || !nlStr.WriteFile(fp) ) return False; writeIt = False; } // End if content length header is wrong } // End if this is content length header//// If this is the Status header, save it for later// else if ( head->key.Equals("status", IGNORE_CASE) ) writeIt = False; if ( writeIt ) { CharC headStr = head->full; if ( !headStr.WriteFile(fp) || !nlStr.WriteFile(fp) ) return False; someWritten = True; } } // End if header is to be written head = head->next; } // End for each header//// Write the status line// if ( statHead && !IsNew() ) { StringC statStr("Status: "); if ( IsRead() ) statStr += 'R'; statStr += "O\n"; if ( !statStr.WriteFile(fp) ) return False; }//// Add a blank line if we wrote anything// if ( someWritten ) { if ( !nlStr.WriteFile(fp) ) return False; } if ( fflush(fp) != 0 ) return False; return True;} // End WriteHeaders/*------------------------------------------------------------------------ * Method to write the body to the specified file */BooleanMsgC::WriteBody(const char *file, Boolean addBlank, Boolean protectFroms){ if ( !bodySizeKnown ) ScanBody(); FILE *fp; fp = fopen(file, "a"); if ( !fp ) { StringC errmsg("Could not open file: "); errmsg += file; errmsg += ".\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); return False; } Boolean success = WriteBody(fp, addBlank, protectFroms); fclose(fp); return success;} // End WriteBody/*------------------------------------------------------------------------ * Method to copy the body text from one file to another */BooleanMsgC::CopyBody(FILE *srcfp, FILE *dstfp, Boolean addBlank, Boolean protectFroms){ if ( !bodySizeKnown ) ScanBody(); CharC nlStr("\n"); long writePos = ftell(dstfp);//// See if we need to worry about converting "From " lines to ">From "// if ( protectFroms && type != UNIX_MSG && (!IsSet(MSG_FROMS_CHECKED) || IsSet(MSG_OPEN_FROMS)) ) { if ( !body->CopyText("", dstfp, srcfp, /*copyHead*/False, /*copyExtHead*/body->IsExternal(), /*copyBody*/True, /*protectFroms*/True, /*restoreFroms*/False, /*endWithNL*/True) ) return False; }//// Else we don't want Froms protected// if ( !protectFroms && type == UNIX_MSG && (!IsSet(MSG_FROMS_CHECKED) || IsSet(MSG_SAFE_FROMS)) ) { if ( !body->CopyText("", dstfp, srcfp, /*copyHead*/False, /*copyExtHead*/body->IsExternal(), /*copyBody*/True, /*protectFroms*/False, /*restoreFroms*/True, /*endWithNL*/True) ) return False; }//// If we don't have any From issues, we can just copy the text as-is// else if ( !body->CopyText("", dstfp, srcfp, /*copyHead*/False, /*copyExtHead*/body->IsExternal(), /*copyBody*/True, /*protectFroms*/False, /*restoreFroms*/False, /*endWithNL*/True) ) return False;//// See if we need to add a blank line// if ( addBlank && body->bodyLines > 0 && !nlStr.WriteFile(dstfp) ) return False; bodyWritePos = writePos; if ( fflush(dstfp) != 0 ) return False; return True;} // End CopyBody/*------------------------------------------------------------------------ * Method to determine the size of this message */u_longMsgC::SpaceNeeded(){ u_long space = 0;//// Loop through headers// HeaderC *head = body->headers; while ( head ) {//// Skip the status header. We'll do it below// if ( !head->key.Equals("status", IGNORE_CASE) ) space += strlen(head->full) + 1/*nl*/; head = head->next; } // End for each header//// Now count the status header// if ( !IsNew() ) { StringC statStr = "Status: "; if ( IsRead() ) statStr += 'R'; statStr += 'O'; space += statStr.size() + 1/*nl*/; }//// Add blank line, body size and any extra needed by derived class// space += 1 + BodyBytes() + ExtraSpaceNeeded(); return space;} // End SpaceNeeded/*------------------------------------------------------------------------ * Method to update the head and body offsets and the head size. The new * offsets will be taken from the last write positions. */voidMsgC::UpdateOffsets(){ long headDelta = headWritePos - body->offset; long bodyDelta = bodyWritePos - body->bodyOffset; if ( headDelta == 0 && bodyDelta == 0 ) return; body->Move(headDelta, bodyDelta);} // End UpdateOffsets#if 0/*------------------------------------------------------------------------ * Method to write the index line to the index file */voidMsgC::WriteIndex(FILE *fp){//// Don't write out the VIEWED bit// u_int tmp = status & (u_int)~MSG_VIEWED; indexOffset = ftell(fp); fprintf(fp, MSG_INDEX_WFMT, tmp, BodyBytes(), BodyLines(), (char*)msgId);}#endif/*------------------------------------------------------------------------ * Method to write the index line to the index file */BooleanMsgC::ReadIndex(FILE *fp){//// Move to the supposed position// if ( indexOffset < 0 || fseek(fp, indexOffset, SEEK_SET) != 0 ) { if ( debuglev > 0 ) cout <<"Bad index offset " <<indexOffset <<" for message " <<number <<endl; return False; }//// Read a line. We can't scan the file directly because sometimes the// message id is blank.//#define MAXLINE 255 char line[MAXLINE+1]; if ( !fgets(line, MAXLINE, fp) ) return False; char buf[128]; buf[0] = 0; u_int statVal; int bytes; int lines; sscanf(line, MSG_INDEX_RFMT, &statVal, &bytes, &lines, buf);//// Check the id// if ( msgId != buf ) { if ( debuglev > 0 ) { cout <<"Bad id in index file for message " <<number <<endl; cout <<"Expecting \"" <<msgId <<"\"" <<endl; cout <<"Got \"" <<buf <<"\"" <<endl; } return False; }//// Save the data// status = statVal; body->bodyBytes = bytes; body->bodyLines = lines; bodySizeKnown = True; body->ComputeSize(); return True;} // End ReadIndex/*------------------------------------------------------------------------ * Method to create message list icon */voidMsgC::CreateIcon(){ if ( icon ) return; icon = new MsgItemC(this); ishApp->mainWin->RegisterMsgIcon(icon);} // End CreateIcon/*------------------------------------------------------------------------ * Method to look for a rule that matches this message in the given rule dict */StringC*MsgC::Match(const RuleDictC& dict){//// Loop through patterns and see if any matches// u_int count = dict.size(); int i=0; for (i=0; i<count; i++) { RegexC *regPat = &dict[i]->key; StringC *strPat = &dict[i]->key;//// Loop through the headers// HeaderC *head = body->headers; CharC full; while ( head ) { full = head->full; if ( regPat->search(full) >= 0 || full.Contains(*strPat, IGNORE_CASE) ) { StringC *rule = &dict[i]->val; return rule; } head = head->next; } } // End for each pattern return NULL;} // End Match/*--------------------------------------------------------------- * Method to build the attribution line for this message */StringCMsgC::Attribution(){ StringC str = ishApp->replyPrefs->attribStr; if ( str.size() > 0 ) ReplaceHeaders(str); return str;}/*--------------------------------------------------------------- * Method to build the "begin forward" line for this message */StringCMsgC::BeginForward(){ StringC str = ishApp->replyPrefs->beginForwardStr; if ( str.size() > 0 ) ReplaceHeaders(str); return str;}/*--------------------------------------------------------------- * Method to build the "end forward" line for this message */StringCMsgC::EndForward(){ StringC str = ishApp->replyPrefs->endForwardStr; if ( str.size() > 0 ) ReplaceHeaders(str); return str;}#if 0/*--------------------------------------------------------------- * Method to return the visible headers */StringCMsgC::DisplayedHeaders(){ HeaderC *head = Headers(); StringC headStr; while ( head ) { if ( prefs->HeaderShown(head->key) ) { headStr += head->full; headStr += "\n"; } head = head->next; } return headStr;} // End DisplayedHeaders#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -