⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msgpartc.c

📁 linux下的E_MAIL客户端源码
💻 C
📖 第 1 页 / 共 4 页
字号:
   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 + -