www.pudn.com > MailSoftware.rar > pop2cmc.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   
#include  
#include  
#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