📄 msgpartc.c
字号:
StringC lab; GetDescription(lab); if ( lab.size() > 0 ) { errmsg += "\nfor part:\n"; errmsg += lab; } halApp->PopupMessage(errmsg); return False; }//// Compute total lines and bytes// ComputeSize(); return True;} // End Scan/*----------------------------------------------------------------------- * Method to count the total number of bytes and lines */voidMsgPartC::ComputeSize(){ if ( headLines >= 0 && bodyLines >= 0 ) { lines = headLines + 1; if ( extLines > 0 ) lines += extLines + extBlank; lines += bodyLines; } if ( headBytes >= 0 && bodyBytes >= 0 ) { bytes = headBytes + 1; if ( extBytes > 0 ) bytes += extBytes + extBlank; bytes += bodyBytes; }}/*----------------------------------------------------------------------- * Method to invalidate the body size */voidMsgPartC::InvalidateSize(){ lines = -1; bytes = -1; bodyLines = -1; bodyBytes = -1;}/*----------------------------------------------------------------------- * Method that returns True if the external body part needs to be * retrieved */BooleanMsgPartC::NeedFetch(){ if ( !IsExternal() || IsLocal() ) return False;//// We have no way of knowing whether mail server attachments have arrived// so we always fetch.// if ( IsMail() ) return True;//// If the attachment permissions are "read-write", we must get the file// again no matter what.// ParamC *param = Param("permission"); if ( param && param->val.Equals("read-write", IGNORE_CASE) ) return True;//// If the file is not here, we need it.// return (dataFile.size() == 0);} // End NeedFetch/*----------------------------------------------------------------------- * Method that returns a message object for this part if the type is * message/rfc822 */FileMsgC*MsgPartC::ChildMsg(){ if ( !Is822() ) return NULL; if ( !childMsg ) { char *name; int childOff = 0; int childLen = 0;//// Use the data file if present// if ( dataFile.size() > 0 ) { name = dataFile; struct stat stats; if ( stat(dataFile, &stats) == 0 ) childLen = (int)stats.st_size; }//// Use the message file if present// else if ( msgFile.size() > 0 ) { name = msgFile; childOff = bodyOffset; childLen = bodyBytes; }//// Create a data file// else { StringC text; if ( bodyBytes > 0 ) text.reSize(bodyBytes); GetText(text, /*fp*/NULL, /*getHead*/False, /*getExtHead*/False, /*getBody*/True, /*restoreFroms*/False); char *cs = tempnam(NULL, "msg."); dataFile = cs; free(cs); delDataFile = True; text.WriteFile(dataFile); name = dataFile; childLen = text.size(); } childMsg = new FileMsgC(name, childOff, childLen, False/*don't delete*/); childMsg->Body(); // To force scanning } // End if child message needed return childMsg;} // End ChildMsg/*--------------------------------------------------------------- * Method to determine if a mime tree contains only plain text parts */BooleanMsgPartC::PlainTextOnly() const{ if ( IsPlainText() ) return True; if ( IsText() ) return False; if ( !IsMultipart() ) return True; // Just a graphic. Plain OK if ( IsAlternative() ) { MsgPartC *altPart = BestAlternative(); return altPart->PlainTextOnly(); } else { MsgPartC *part = child; while ( part ) { if ( !part->PlainTextOnly() ) return False; part = part->next; } } return True;} // End PlainTextOnly/*-------------------------------------------------------------------- * Method to count the children */intMsgPartC::ChildCount() const{ int count = 0; MsgPartC *part = child; while ( part ) { count++; part = part->next; } return count;}/*-------------------------------------------------------------------- * Method to determine how many non-multipart parts there are in this * tree. */intMsgPartC::LeafCount() const{ int count = 0;//// Loop through children// MsgPartC *part = child; while ( part ) { if ( part->IsMultipart() ) count += part->LeafCount(); else count++; part = part->next; } return count;} // End LeafCount/*--------------------------------------------------------------- * Method to copy the text as it appears in the mail message. */BooleanMsgPartC::CopyText(char *ofile, FILE *ofp, FILE *ifp, Boolean copyHead, Boolean copyExtHead, Boolean copyBody, Boolean protectFroms, Boolean restoreFroms, Boolean endWithNL) const{ if ( copyHead && copyBody ) copyExtHead = True; else if ( !IsExternal() ) copyExtHead = False; if ( !copyBody ) { protectFroms = False; restoreFroms = False; } if ( msgFile.size() == 0 ) { if ( parentMsg && parentMsg->IsImap() ) { StringC text; return (parentMsg->GetPartText(this, text, copyHead, copyExtHead, copyBody) && text.WriteFile(ofp)); } else return False; }//// Figure out how much to copy// int off = 0; int len = 0; if ( copyHead && copyBody ) { // Assume copyExtHead off = offset; len = bytes; } else if ( copyHead && copyExtHead ) { off = offset; len = headBytes+1+extBytes; } else if ( copyExtHead && copyBody ) { off = extOffset; len = extBytes+1+bodyBytes; } else if ( copyHead ) { off = offset; len = headBytes; } else if ( copyExtHead ) { off = extOffset; len = extBytes; } else if ( copyBody ) { off = bodyOffset; len = bodyBytes; }//// Perform the copy// return CopyText(ofile, ofp, ifp, off, len, protectFroms, restoreFroms, endWithNL);} // End CopyText/*--------------------------------------------------------------- * Method to copy the text as it appears in the mail message. */BooleanMsgPartC::CopyText(char *ofile, FILE *ofp, FILE *ifp, int off, int len, Boolean protectFroms, Boolean restoreFroms, Boolean endWithNL) const{ if ( msgFile.size() == 0 ) return False; Boolean closeInput = (ifp == NULL); if ( !ifp ) { ifp = fopen(msgFile, "r"); if ( !ifp ) { StringC errmsg("Could not open file: \""); errmsg += msgFile; errmsg += "\".\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); return False; } } fseek(ifp, off, SEEK_SET); int remaining = len; char buffer[BUFLEN]; buffer[0] = 0; Boolean error = False; Boolean lastNL = False; if ( protectFroms || restoreFroms ) { RegexC *fromPat = UnixFolderC::fromPat; CharC bufStr; while ( remaining > 0 ) {//// Read a line from the source file// if ( !fgets(buffer, BUFLEN-1, ifp) ) { StringC errmsg("Could not read file: \""); errmsg += msgFile; errmsg += "\".\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); if ( closeInput ) fclose(ifp); return False; }//// See if it needs protecting// Boolean error = False; bufStr = buffer; if ( protectFroms && buffer[0] == 'F' ) { if ( bufStr.StartsWith("From ") && (!fromPat || fromPat->match(bufStr)) ) { error = (fwrite(">", 1, 1, ofp) != 1); } }//// See if it needs restoring// else if ( restoreFroms && buffer[0] == '>' ) { if ( bufStr.StartsWith(">From ") && (!fromPat || fromPat->match(bufStr, 1)) ) { bufStr.CutBeg(1); } }//// Write bytes to destination file// if ( !error ) error = !bufStr.WriteFile(ofp); if ( error ) { StringC errmsg("Could not write file: \""); errmsg += ofile; errmsg += "\".\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); if ( closeInput ) fclose(ifp); return False; } lastNL = bufStr.EndsWith('\n'); remaining -= strlen(buffer); } // End while bytes remain to be copied } // End if Froms may need protecting or restoring else { while ( remaining > 0 ) { int count = MIN(remaining, BUFLEN-1);//// Read bytes from source file// int check = fread(buffer, 1, count, ifp); if ( check <= 0 && ferror(ifp) ) { StringC errmsg("Could not read file: \""); errmsg += msgFile; errmsg += "\".\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); if ( closeInput ) fclose(ifp); return False; }//// Write bytes to destination file// count = check; buffer[count] = 0; check = fwrite(buffer, 1, count, ofp); if ( check != count ) { StringC errmsg("Could not write file: \""); errmsg += ofile; errmsg += "\".\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); if ( closeInput ) fclose(ifp); return False; } lastNL = (buffer[count-1] == '\n'); remaining -= count; if (feof(ifp)) remaining = 0; } // End while bytes remain to be copied } // End if no From issues//// If the body didn't end with a newline, write one// if ( !error && len > 0 && endWithNL && !lastNL ) error = (fwrite("\n", 1, 1, ofp) != 1); if ( !error ) error = (fflush(ofp) != 0); if ( closeInput ) fclose(ifp); return !error;} // End CopyText/*--------------------------------------------------------------- * Method to copy the source for this part to a file */BooleanMsgPartC::WriteFile(char *ofile, FILE *ofp){ Boolean closeOutput = (ofp == NULL); if ( !ofp ) { ofp = fopen(ofile, "r"); if ( !ofp ) { StringC errmsg("Could not open file: \""); errmsg += ofile; errmsg += "\".\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); return False; } }//// If there's no message file, we have to get the text.// FILE *ifp = NULL; StringC text; if ( msgFile.size() == 0 ) { if ( bodyBytes > 0 ) text.reSize(bodyBytes); GetText(text, /*fp*/NULL, /*getHead*/True, /*getExtHead*/True, /*getBody*/True, /*restoreFroms*/False); } else { ifp = fopen(msgFile, "r"); if ( !ifp ) { StringC errmsg("Could not open file: \""); errmsg += msgFile; errmsg += "\".\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); if ( closeOutput ) fclose(ofp); return False; } fseek(ifp, offset, SEEK_SET); } Boolean error = False;//// Write the content-type header if it is not present in the source// if ( defConType ) { StringC headStr("Content-Type: "); headStr += conStr; headStr += '\n'; error = !headStr.WriteFile(ofp); }//// Copy the source// int remaining = (ifp ? bytes : text.length()); char buffer[BUFLEN]; buffer[0] = 0; while ( !error && remaining > 0 ) { int count = MIN(remaining, BUFLEN-1); int check;//// Read bytes from source file// if ( ifp ) { check = fread(buffer, 1, count, ifp); if ( check <= 0 ) { StringC errmsg("Could not read file: \""); errmsg += msgFile; errmsg += "\".\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); error = True; } } else { check = text.length(); }//// Write bytes to destination file// if ( !error ) { count = check; if ( ifp ) { buffer[count] = 0; check = fwrite(buffer, 1, count, ofp); } else { check = fwrite((char*)text, 1, count, ofp); } if ( check != count ) { StringC errmsg("Could not write file: \""); errmsg += ofile; errmsg += "\".\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); error = True; } } remaining -= count; } // End while bytes remain to be copied if ( ifp ) fclose(ifp); if ( closeOutput ) fclose(ofp); return !error;} // End WriteFile/*--------------------------------------------------------------- * Method to create the data file if it doesn't exist. */BooleanMsgPartC::CreateDataFile(){ if ( dataFile.size() > 0 ) return True; if ( IsExternal() ) return False;//// Read the data// StringC bodyStr; if ( !GetData(bodyStr) ) return False;//// Reading the body may have created the data file// if ( dataFile.size() > 0 ) return True;//// We must create the data file// char *cs = tempnam(NULL, "data."); dataFile = cs; if ( conType == CT_HTML ) { // Some brain-damaged MUAs generating HTML mails omit the encapsulating // <HTML></HTML> tags so we'll have to tell the browser to display this // as a valid HTML doc via the proper file extension. dataFile += ".html"; } delDataFile = True; free(cs); if ( !bodyStr.WriteFile(dataFile) ) { StringC errmsg = "Could not write file: \""; errmsg += dataFile; errmsg += "\".\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); unlink(dataFile); dataFile.Clear(); delDataFile = False; return False; } return True;} // End CreateDataFile
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -