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

📄 pop2cmc.cpp

📁 email client and support pop3、smtp、imap protocol.
💻 CPP
字号:
//      
// implementation of pop3 to cmc/mapi mail forward
// currently only base64 decoding supported
// Pop2cmc.cpp: implementation of the Pop2cmc class.
// NO WARRANTY!
// USE AT YOUR OWN RISK
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <stdio.h> 
#include <string.h>
#include <winbase.h>
#include "InetServer.h"
#include "Pop2cmc.h"
#include "wrap2cmc.h"

#include "base64.h" // public domain code for encoding/decoding

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

extern Wrap2CMC	CMCObject ;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Pop2cmc::Pop2cmc()
{
	VERIFY(CMCReceiver = new CMC_recipient[16]);
	CMCAttach   = 0  ;
	CMCMessage  = 0  ;
	mime_cntrfr_val = mime_char_val   = mime_cont_val   = 0 ;
	mime_cndisp_val = mime_cndisc_val = mime_fname_val  = 0 ;
	mime_name_val   = Mailboundary    = MailSubject      = 0 ;
	MailFrom         = 0 ;
}

Pop2cmc::~Pop2cmc()
{
	delete [] CMCReceiver ;
        //delete [] CMCAttach   ;
        //delete CMCMessage ;
}

  


int Pop2cmc::ParsePOP3nSend(CString cMFileName)
{
	
    char tempstr[255] ;
	char MailFile[50];
	long err = 999 ; 
	if ( GetCurrentDirectory( 255,tempstr ) == 0 ) 
	{
		return 200 ; // system command failed
	}

        sprintf(MailPath,"%s\\cmcqueue\\",tempstr);
        sprintf(MailFile,"%s",cMFileName);
	if ( ! ReadMailFile(cMFileName)) 
		return 300 ; // 	
    int PathLength = strlen(MailPath);
	
	LPCTSTR lpcmsg = MailMessage ;
	
	// build attachment
	if ( isMultiPart )
	{
		int pathLength = strlen(MailPath);                         
		if ( isParsedFully ) 
		{
			VERIFY(CMCAttach = new CMC_attachment[nOfAttachment]);
			for ( int j = 0 ; j < nOfAttachment ; j++ )
			{
				CMCAttach[j].attach_title = MailAttachment[j]+pathLength  ;
				CMCAttach[j].attach_filename = MailAttachment[j] ;
				CMCAttach[j].attach_type        = CMC_ATT_OID_BINARY   ;
				CMCAttach[j].attach_flags               = 0                                    ;
				CMCAttach[j].attach_extensions  = NULL                                 ;
			}
				CMCAttach[nOfAttachment-1].attach_flags= CMC_ATT_LAST_ELEMENT ;
		}
		else
		{
			VERIFY(CMCAttach = new CMC_attachment[1]);
			sprintf(tempstr,"%s%s",MailPath,MailFile);
			CMCAttach[0].attach_title = MailFile       ;
			CMCAttach[0].attach_filename = tempstr ;
			CMCAttach[0].attach_type  = CMC_ATT_OID_BINARY   ;
			CMCAttach[0].attach_flags = CMC_ATT_LAST_ELEMENT ;
			CMCAttach[0].attach_extensions    = NULL                                 ;
		}
	}

	CMCReceiver[nOfReceiver-1].recip_flags = CMC_RECIP_LAST_ELEMENT ; 
		 
        VERIFY(CMCMessage = new CMC_message) ;
	/*  Put it together in the message structure. */
        CMCMessage->message_reference   = NULL;     
        CMCMessage->message_type        = NULL;     
	CMCMessage->subject             = (char *) MailSubject;    /* Message subject          */
	CMCMessage->time_sent           = CMCTime;    /* Ignored on cmc_send calls. */
        CMCMessage->text_note           = (char *) lpcmsg ;   
        CMCMessage->recipients          = CMCReceiver ; 
        CMCMessage->attachments         = CMCAttach ;    
	CMCMessage->message_flags       = 0;          /* No flags                 */
	CMCMessage->message_extensions  = NULL;       /* No message extensions    */


	err = CMCObject.CMCSend(CMCMessage) ;
	CleanAttachment();
	if ( MailSubject)	delete [] MailSubject ;
	MailSubject = 0 ;
	if ( MailFrom )		delete [] MailFrom        ;
    MailFrom = 0 ;

	if ( CMCMessage ) delete CMCMessage	  ;
	MailMessage = "" ;
	MailMessage.FreeExtra();
	for (int i = 0 ; i < nOfReceiver ; i++ )
	{
		delete [] CMCReceiver[i].name ;
		delete [] CMCReceiver[i].address ;
	}
	delete [] CMCAttach ;
	CMCAttach = 0 ;
	return err  ;
}



BOOL Pop2cmc::ReadMailFile(CString cMFileName)
{
    char tempstr[255] ;
    pop3file = fopen(MailPath + cMFileName,"r");
    if ( pop3file == NULL )
    {

		// TODO log error message
        //MessageBox(NULL,"File open failed",NULL,MB_OK);
		return FALSE ;
    }
    Mailboundary = MailSubject = MailFrom = 0 ;
    isB64 = isMultiPart = isParsedFully = FALSE ;
    nOfReceiver = nOfAttachment = 0 ;
    while ( !feof(pop3file) )
    {
		fgets(tempstr,255,pop3file);
		if(	tempstr[0]	== 'X'	&&	tempstr[1]	== '-'	&&
			tempstr[2]	== 'C'	&&	tempstr[3]	== 'M'	&&
			tempstr[4]	== 'C'	&&	tempstr[5]	== 'E'	&&
			tempstr[6]	== 'N'	&&	tempstr[7]	== 'D'	&&
			tempstr[8]  == '\n'  ) 
			break ;

            BuildCMCAddress(tempstr);  
    }
	BuildHeader();
	BuildBody();
	BuildAttachment();
	fclose(pop3file);
	return TRUE ;
}


// RFC822 doesn't specify about header length but says
// there should be a blank line (CR+LF) between header & message body
BOOL Pop2cmc::BuildHeader()
{
	char tempstr[512] ;
	char *ptr = 0 ; 
	char *cont_val		= 0 ;	// Content-Type 
	char *char_val		= 0 ;	// charset
	char *cntrfr_val	= 0 ;	// content-transfer-encoding 
    char *MailHeader = 0 ;
	VERIFY(MailHeader = new char[1024]);
	strcpy(MailHeader,"");

	while( fgets(tempstr,512,pop3file) )
	{
		if ( !strnicmp(tempstr,"\r\n",2) )
		{
			break ; // 
		}
          strcat(MailHeader,tempstr);
	} // end of while loop


    if ( ptr = strstr(MailHeader,"From:") )
    {
		for(int j = 0 ; j < 5 ; j++ , ptr++);
		MailFrom = getCleanStr(ptr);
    }
    if ( ptr = strstr(MailHeader,"\nSubject:") )
    {
        for(int j = 0 ; j < 9 ; j++ , ptr++);  
		MailSubject = getCleanStr(ptr);
    }
    
	if ( ptr = strstr(MailHeader,"\nContent-Type:") )
	{
		if ( !strnicmp(ptr,"\nContent-Type: multipart/mixed",29 ) )
        {
			isMultiPart = TRUE ;
			if ( ptr = strstr(ptr,"boundary=") )
			{
				for (int j = 0 ; j < 9 ; j++ , ptr++ ) ;
				pop3boundary(ptr) ;
			}
		   // TODO 
		}
        else if ( !strnicmp(ptr,"\nContent-Type: text/plain",24) )
        {
			isMultiPart = FALSE ;
		}

		
		if (cont_val = strstr(ptr,"Content-Type:") )
		{
			for (int j = 0 ; j < 13 ; j++ , cont_val++);
			mime_cont_val = getCleanStr(cont_val);			
		}
		if ( char_val = strstr(ptr,"charset=") )
		{
			for (int j = 0 ; j < 8 ; j++ , char_val++);
			mime_char_val = getCleanStr(char_val);			
		}
		if ( cntrfr_val = strstr(ptr,"Content-Transfer-Encoding:") )	
		{
			for (int j = 0 ; j < 26 ; j++ , cntrfr_val++);
			mime_cntrfr_val = getCleanStr(cntrfr_val);			
		}

	}
	delete [] MailHeader ;
	return TRUE ; 
}

void Pop2cmc::BuildBody()
{

	char tempstr[512] ;

	MailMessage += "(SMTP2MAPI Forwarder) \r\n" ;
	MailMessage += "From : " ;
	MailMessage += MailFrom ;
	MailMessage += "\r\n" ;
	MailMessage += "\r\n" ;
	
	// Multipart messages have message boundary for body of mail
	if ( isMultiPart )  
	{

		// start parsing body of message for encoding used
		do
		{
			if ( !strnicmp(tempstr,Mailboundary,strlen(Mailboundary)) )
			{	
				break ;
			}
                } while(fgets(tempstr,512,pop3file) ) ;
		
		ParseMimeHdr();
	}
	
	// build message body 
	while ( fgets(tempstr,512,pop3file) != NULL )  
	{
		if ( isMultiPart && !strnicmp(tempstr,Mailboundary,strlen(Mailboundary)))
		{
			break ;
			
		}
		else if ( !strnicmp(tempstr,".\r\n",3) &&	!isMultiPart )
		{
			break ; 
		}
		MailMessage +=tempstr ;
        }
	CleanMimeHdr();
}

void Pop2cmc::BuildAttachment()
{
	char tempstr[512] ; 
	nOfAttachment = 0 ; 
	if ( !isMultiPart )
		return ;

	while ( !feof(pop3file) )  
	{
		isB64 = FALSE	;
		is7bt = FALSE	;
		is8bt = FALSE	;
		isQtp = FALSE	;
		isUen = FALSE	;
		isBin = FALSE	;
		isXen = FALSE	;
		isParsedFully = TRUE ;  // if not parsed fully we will send
								// mail file as one attachement
		ParseMimeHdr();
		if ( mime_cont_val || mime_char_val || mime_cntrfr_val || mime_cndisp_val || mime_name_val || mime_fname_val )
		{

			if ( !strnicmp(mime_cntrfr_val,"base64",6) ) 
				isB64 = TRUE ;
			else
			{
				if ( !strnicmp(mime_cntrfr_val,"quoted-printable",16)) 
					isQtp = TRUE ;
				if ( !strnicmp(mime_cntrfr_val,"8bit",4)) 
					is8bt = TRUE ;
				if ( !strnicmp(mime_cntrfr_val,"7bit",4)) 
					is7bt = TRUE ;
				if ( !strnicmp(mime_cntrfr_val,"uuencoded",9)) 
					isUen = TRUE ;
				if ( !strnicmp(mime_cntrfr_val,"binary",6)) 
					isBin = TRUE ;
				if ( !strnicmp(mime_cntrfr_val,"X-EncodingName",14)) 
					isXen = TRUE ;
				isParsedFully = FALSE ;
			}

			char tmpfile[128] ;
			nOfAttachment++	 ;
			if ( mime_name_val )
			{
				sprintf(tmpfile,"%s%s",MailPath,mime_name_val);
			}
			else if ( mime_fname_val )
			{
				sprintf(tmpfile,"%s%s",MailPath,mime_fname_val);
			}
			else
			{	
				char file[30] ;
				sprintf(file,"mes%d.out",nOfAttachment);	
				sprintf(tmpfile,"%s%s",MailPath,file);
			}
	
			VERIFY(MailAttachment[nOfAttachment-1] = new char[strlen(tmpfile)+1]) ;
			strcpy(MailAttachment[nOfAttachment-1],tmpfile);
	
			fstream outf(tmpfile,ios::in|ios::out|ios::binary) ;
			
			
			// othere decoding scheme will be added in future
			if ( isB64 )
			{
				Base64Decoder b64(outf);
                                while (fgets(tempstr,100,pop3file))
				{
				    if ( !strnicmp(tempstr,Mailboundary,strlen(Mailboundary)) )
					{
						break ;
					}
					b64.Put((unsigned char*)(tempstr),strlen(tempstr));
				}
				b64.InputFinished();
			}
                        if ( isQtp )
                        {




                        }
		}
	}
	CleanMimeHdr();
	return ;		
}





// this function will create message boundary
void Pop2cmc::pop3boundary(char *mBoundary)
{
	char *buf = 0 ;
        VERIFY(buf = new char[strlen(mBoundary)+4]) ;
	if ( *mBoundary == '\"' ) mBoundary++ ;
	strcpy(buf,"--");
	sscanf(mBoundary,"%[^\"\r\n]",buf+2);
        VERIFY(Mailboundary = new char[strlen(buf)+1]);
	strcpy(Mailboundary,buf);
	delete [] buf ;
}


char * Pop2cmc::pop3filename(char *fname)
{
	char *buf = 0 ;
	VERIFY(buf = new char[strlen(fname)+2]) ;
	if ( *fname == '\"' ) fname++ ;
	sscanf(fname,"%[^\"\r\n]",buf);
	return buf ;
}

void Pop2cmc::CleanAttachment()
{
	if ( ! isMultiPart )
		return ;
	for(int j = 0 ; j < nOfAttachment ; j++)
	{
		DeleteFile(MailAttachment[j]);
	}
	delete [] *MailAttachment ;
}

void Pop2cmc::ParseMimeHdr()
{
	char tempstr[512] ;
	char *cont_val		= 0 ;	// Content-Type 
	char *char_val		= 0 ;	// charset
	char *cntrfr_val	= 0 ;	// content-transfer-encoding 
	char *cndisp_val	= 0	;	// content-disposition
	char *cndisc_val	= 0 ;	// content-description
	char *fname_val		= 0 ;	// filename
	char *name_val		= 0 ;	// name
	char mimeHeader[512]	; 

	strcpy(mimeHeader,"");
	while(fgets(tempstr,512,pop3file) ) 
	{
		if ( !strnicmp(tempstr,"\r\n",2) )
			break ;
		strcat(mimeHeader,tempstr);
	} 

	strcpy(tempstr,mimeHeader);
	char2lower(tempstr) ;
	if (cont_val = strstr(tempstr,"content-type:") )
	{
		for (int j = 0 ; j < 13 ; j++ , cont_val++);
		mime_cont_val = getCleanStr(cont_val);			
	}
	if ( char_val = strstr(tempstr,"charset=") )
	{
		for (int j = 0 ; j < 8 ; j++ , char_val++);
		mime_char_val = getCleanStr(char_val);			
	}
	if ( cntrfr_val = strstr(tempstr,"content-transfer-encoding:") )
	{
		for (int j = 0 ; j < 26 ; j++ , cntrfr_val++);
		mime_cntrfr_val = getCleanStr(cntrfr_val);			
	}
	if ( name_val = strstr(tempstr," name=") ) // avoid filename
	{
		for (int j = 0 ; j < 6 ; j++ , name_val++);
		mime_name_val = getCleanStr(name_val);			
	}
	if ( fname_val = strstr(tempstr,"filename=") )
	{
		for (int j = 0 ; j < 9 ; j++ , fname_val++);
		mime_fname_val = getCleanStr(fname_val);			
	}
	if ( cndisp_val = strstr(tempstr,"content-disposition:") )
	{	
		for (int j = 0 ; j < 20 ; j++ , cndisp_val++);
		mime_cndisp_val = getCleanStr(cndisp_val);			
	}
	if ( cndisc_val = strstr(tempstr,"content-description:") )
	{
		for (int j = 0 ; j < 20 ; j++ , cndisc_val++);
		mime_cndisc_val = getCleanStr(cndisc_val);			
	}
}


void Pop2cmc::char2lower(char *tempstr)
{
	int length = strlen(tempstr);
	for (int i=0; i<length; i++)
	{
		tempstr[i] = tolower(tempstr[i]) ;
	}
	
}

char * Pop2cmc::getCleanStr(char *tempstr)
{       
	char *lbufret = 0 ;
	VERIFY(lbufret = new char[strlen(tempstr)+1]) ;
	for ( ; *tempstr == ' ' ; tempstr++) ;
	if ( *tempstr == '\"' ) tempstr++ ;
	sscanf(tempstr,"%[^;\"\r\n]",lbufret);
	for ( int j = strlen(lbufret) ; lbufret[j] == '\0' || lbufret[j] == '\r' || lbufret[j] == '\n' ; j-- )
		lbufret[j] = '\0' ;
	return lbufret ; 
}


void Pop2cmc::BuildCMCAddress(LPSTR tempstr)
{
    LPSTR lpszName  = 0  ;
    VERIFY(lpszName = new CHAR[64]);
    LPSTR lpszAddress = 0 ;
    VERIFY(lpszAddress = new CHAR[47]);
    
	int i ;

    if ( nOfReceiver == 16 )
        return ;
    

    for (  ; *tempstr != ':' ;tempstr++ );
    tempstr++ ;

    for ( i = 0 ; *tempstr != ';' ; tempstr++ , i++ )
        lpszName[i] = *tempstr ;
    
	lpszName[i] = '\0' ;
	
    tempstr++;

    for ( i = 0 ; *tempstr != ';' ; tempstr++ , i++ )
        lpszAddress[i] = *tempstr ;

    lpszAddress[i] = '\0' ;
	
    // Build recipient list with two recipients.  Add one "To" recipient. 
	CMCReceiver[nOfReceiver].name       = (char *) lpszName;      
	CMCReceiver[nOfReceiver].name_type  = CMC_TYPE_INDIVIDUAL;    
	CMCReceiver[nOfReceiver].address    = (char *) lpszAddress  ; 
	CMCReceiver[nOfReceiver].role       = CMC_ROLE_TO;            
	CMCReceiver[nOfReceiver].recip_flags= 0    ; 
	CMCReceiver[nOfReceiver].recip_extensions = NULL;             
	nOfReceiver++ ;
}


void Pop2cmc::CleanMimeHdr()
{
	if ( mime_cont_val)		delete [] mime_cont_val    ;
	if ( mime_char_val)		delete [] mime_char_val    ; 
	if ( mime_cntrfr_val)	delete [] mime_cntrfr_val  ; 
	if ( mime_cndisp_val)	delete [] mime_cndisp_val  ; 
	if ( mime_cndisc_val)	delete [] mime_cndisc_val  ; 
	if ( mime_fname_val)	delete [] mime_fname_val   ; 
	if ( mime_name_val)		delete [] mime_name_val    ;
	mime_cont_val	= mime_char_val		= 0 ;	
	mime_cntrfr_val	= mime_cndisp_val	= 0	;	
	mime_cndisc_val	= mime_fname_val	= 0 ;	
	mime_name_val	= 0 ;	

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -