www.pudn.com > popmail.zip > POPLevel.cpp


// POPLevel.cpp : Implementation of CPOPLevel 
#include "stdafx.h" 
#include "Pophandler.h" 
#include "POPLevel.h" 
#include "SmartWSA.h" 
 
///////////////////////////////////////////////////////////////////////////// 
// CPOPLevel 
 
HRESULT	CPOPLevel::FinalConstruct() 
{ 
	m_pcSmartWSA = new CSmartWSA; 
	ATLASSERT(m_pcSmartWSA); 
	m_pcPOP3 = new CPop3Connection; 
	ATLASSERT(m_pcPOP3); 
	return S_OK; 
} 
 
void CPOPLevel::FinalRelease() 
{ 
	delete m_pcPOP3; 
	delete m_pcSmartWSA; 
} 
 
 
STDMETHODIMP CPOPLevel::InterfaceSupportsErrorInfo(REFIID riid) 
{ 
	static const IID* arr[] =  
	{ 
		&IID_IPOPLevel 
	}; 
	for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++) 
	{ 
		if (InlineIsEqualGUID(*arr[i], riid)) 
			return S_OK; 
	} 
	return S_FALSE; 
} 
 
 
STDMETHODIMP CPOPLevel::get_Host(BSTR *pVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
 
	ATLASSERT(pVal); 
	try 
	{ 
		*pVal = m_bstHost.copy(); 
	} 
	catch(...) 
	{ 
		return E_FAIL; 
	} 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::put_Host(BSTR newVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
 
	try 
	{ 
		m_bstHost = newVal; 
	} 
	catch(...) 
	{ 
		return E_FAIL; 
	} 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::get_Port(long *pVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
 
	ATLASSERT(pVal); 
	*pVal = (LONG)m_dwPort; 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::put_Port(long newVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
 
	m_dwPort = (DWORD) newVal; 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::get_User(BSTR *pVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
 
	ATLASSERT(pVal); 
 
	try 
	{ 
		*pVal = m_bstUser.copy(); 
	} 
	catch(...) 
	{ 
		return E_FAIL; 
	} 
	 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::put_User(BSTR newVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
 
	try 
	{ 
		m_bstUser = newVal; 
	} 
	catch(...) 
	{ 
		return E_FAIL; 
	} 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::get_Password(BSTR *pVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
 
	ATLASSERT(pVal); 
	try 
	{ 
		*pVal = m_bstPassword.copy(); 
	} 
	catch(...) 
	{ 
		return E_FAIL; 
	} 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::put_Password(BSTR newVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
 
	try 
	{ 
		m_bstPassword = newVal; 
	} 
	catch(...) 
	{ 
		return E_FAIL; 
	} 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::get_Timeout(long *pVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
 
	ATLASSERT(pVal); 
	*pVal = (LONG)m_pcPOP3->GetTimeout(); 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::put_Timeout(long newVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
 
	m_pcPOP3->SetTimeout(newVal); 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::Connect() 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
	 
	BOOL blRet = m_pcPOP3->Connect(m_bstHost, m_bstUser, m_bstPassword, m_dwPort); 
	if(blRet == false) 
		return E_FAIL; 
	//return E_FAIL; 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::Disconnect() 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
 
	BOOL blRet = m_pcPOP3->Disconnect(); 
	if(blRet == false) 
		return E_FAIL; 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::GetMailCount(long *a_plCount) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
 
	ATLASSERT(a_plCount); 
	 
	INT iSize; 
	INT iCount; 
	BOOL blRet = m_pcPOP3->Statistics(iCount, iSize); 
	if(blRet == false) 
		return E_FAIL; 
	 
	*a_plCount = iCount; 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::GetMail(long a_lMailNum, long a_lDelete) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
 
	FILE* pfTemp	= NULL; 
	FILE* pfAttach	= NULL; 
	try 
	{ 
// clear attached files	 
	m_bstAttachedFiles = ""; 
// clear body 
	m_bstBody = ""; 
 
// get mail message 
	BOOL blRet = m_pcPOP3->Retrieve(a_lMailNum, m_cMessage); 
	if(blRet == false) 
		return E_FAIL; 
	if(a_lDelete > 0) 
	{ 
	// mark message as del 
		m_pcPOP3->Delete(a_lMailNum); 
	} 
// write raw body to the file 
	pfTemp = fopen("temp.mme", "w+b"); 
	ATLASSERT(pfTemp); 
 
	CString sRawBody = m_cMessage.GetRawBody(); 
	fputs(sRawBody, pfTemp); 
	fclose(pfTemp); 
	pfTemp = NULL; 
 
// get boundary 
	CString sBoundary = m_cMessage.GetBoundary(); 
// open file 
	pfTemp = fopen("temp.mme", "rb"); 
	ATLASSERT(pfTemp); 
	CHAR text[1024] = ""; 
	bool blIsBodyEmpty = false; 
// store position for the empty body 
	LONG lPos = ftell(pfTemp); 
// get opening boundary string 
	if(sBoundary.GetLength() != 0) 
	{ 
		while(fgets(text, sizeof(text) - 1, pfTemp)) 
		{ 
			if( !strncmp(text, "--", 2) && !strncmp(text + 2, sBoundary, strlen(sBoundary))) 
				break; 
		} 
	// local headers    
	// get header out of the way 
		while(fgets(text, sizeof(text) - 1, pfTemp)) 
		{ 
			if((*text == '\n') || (*text == '\r') || !*text) 
				break; 
			if(strncmp(text, "Content-Disposition: attachment", strlen("Content-Disposition: attachment")) == 0) 
			{ 
				blIsBodyEmpty = true; 
			} 
		} 
	} 
 
// read body 
	CString sBody; 
	if(blIsBodyEmpty == false) 
	{ 
		memset(text, 0, sizeof(text));	 
		while(fgets(text, sizeof(text) - 1, pfTemp)) 
		{ 
			if(sBoundary.GetLength() != 0) 
			{ 
				if(!strncmp(text, "--", 2) && !strncmp(text + 2, sBoundary, strlen(sBoundary))) 
					break; 
			} 
			sBody += text; 
			if(strlen(text) >= 2) 
			{ 
				if( (text[strlen(text) - 2] == 0x0d) && ((text[strlen(text) - 1] == 0x0a) ) ) 
				{ 
					sBody = sBody.Left(sBody.GetLength() - 2); 
					sBody += "\n"; 
				} 
			} 
		} 
	} 
 
// check is it multipart 
	CString sContentType = m_cMessage.GetContentType(); 
	if(sContentType.Compare("multipart/mixed") != 0) 
	{ 
		m_bstBody = sBody; 
		fclose(pfTemp); 
		pfTemp = NULL; 
		remove("temp.mme");	 
		return S_OK; 
	} 
 
	if(sBody.GetLength() > 2) 
		sBody = sBody.Left(sBody.GetLength() - 2); 
 
	m_bstBody = sBody; 
	if(blIsBodyEmpty == false) 
	// store new position	 
		lPos = ftell(pfTemp); 
 
// now parse attached files 
	fseek(pfTemp, lPos, SEEK_SET); 
	CHAR* pszStr = NULL; 
	while(true) 
	{ 
	// local headers    
	// get header out of the way 
		while( (pszStr = fgets(text, sizeof(text) - 1, pfTemp)) ) 
		{ 
			if((*text == '\n') || (*text == '\r') || !*text) 
				break; 
		// try to get filename 
		// Content-Disposition: attachment; filename="New Text Document.txt" 
			if(strncmp(text, "Content-Disposition: attachment; filename=", strlen("Content-Disposition: attachment; filename=")) == 0) 
			{ 
				CString sFileName = text + strlen("Content-Disposition: attachment; filename=") + 1; 
				if(sFileName.GetLength() <= 3) 
				{ 
					fclose(pfTemp); 
					pfTemp = NULL; 
					remove("temp.mme");	 
					return E_FAIL; 
				} 
				sFileName = sFileName.Left(sFileName.GetLength() - 3); 
			// try to open file 
				pfAttach = fopen(sFileName, "w+b"); 
				ATLASSERT(pfAttach); 
				m_bstAttachedFiles += (LPCTSTR)sFileName; 
				m_bstAttachedFiles += "\n"; 
			} 
		} 
		 
	// read current attachment		 
		memset(text, 0, sizeof(text)); 
		while( (pszStr = fgets(text, sizeof(text) - 1, pfTemp)) ) 
		{ 
			if(!strncmp(text, "--", 2) && !strncmp(text + 2, sBoundary, strlen(sBoundary))) 
				break;       
			LONG	x		= 0; 
			LONG	triplet	= 0;  
			LONG	qpos	= 0; 
			LONG	equals	= 0; 
 
			while(text[x]) 
			{ 
				if(base64_valid(text[x])) 
				{ 
					if(text[x] == '=') 
					{ 
						equals++; 
					} 
					else 
						triplet |= (base64_get_value(text[x]) << ((3 - qpos) * 6)); 
					qpos++; 
				} 
		 
				if(qpos == 4) 
				{ 
					fputc((triplet & 0xFF0000) >> 16, pfAttach); 
					if(equals < 2) 
						fputc((triplet & 0xFF00) >> 8, pfAttach); 
					if(!equals) 
						fputc((triplet & 0xFF), pfAttach); 
			 
					triplet = 0; 
					qpos	= 0; 
				} 
				x ++; 
			} 
			memset(text, 0, sizeof(text)); 
		} 
		if(pfAttach) 
		{ 
			fclose(pfAttach); 
			pfAttach = NULL; 
		} 
 
		if(pszStr == NULL) 
		{ 
		// eof, stopping 
			break; 
		} 
	} 
 
	fclose(pfTemp); 
	remove("temp.mme");	 
	} 
	catch (...)  
	{ 
		if(pfTemp) 
			fclose(pfTemp); 
		if(pfAttach) 
			fclose(pfAttach); 
		remove("temp.mme"); 
		return E_FAIL; 
	} 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::get_From(BSTR *pVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
	ATLASSERT(pVal); 
 
	try 
	{ 
		bstr_t bstFrom; 
		bstFrom	= m_cMessage.GetFrom(); 
	 
		*pVal = bstFrom.copy(); 
	} 
	catch(...) 
	{ 
		return E_FAIL; 
	} 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::get_To(BSTR *pVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
	ATLASSERT(pVal); 
 
	try 
	{ 
		bstr_t bstTo; 
		bstTo	= m_cMessage.GetTo(); 
	 
		*pVal = bstTo.copy(); 
	} 
	catch(...) 
	{ 
		return E_FAIL; 
	} 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::get_CC(BSTR *pVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
	ATLASSERT(pVal); 
 
	try 
	{ 
		bstr_t bstCC; 
		bstCC = m_cMessage.GetCC(); 
	 
		*pVal = bstCC.copy(); 
	} 
	catch(...) 
	{ 
		return E_FAIL; 
	} 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::get_Date(BSTR *pVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
	ATLASSERT(pVal); 
 
	try 
	{ 
		bstr_t bstDate; 
		bstDate	= m_cMessage.GetDate(); 
	 
		*pVal = bstDate.copy(); 
	} 
	catch(...) 
	{ 
		return E_FAIL; 
	} 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::get_Header(BSTR *pVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
	ATLASSERT(pVal); 
 
	try 
	{ 
		bstr_t bstHeader; 
		bstHeader	= m_cMessage.GetHeader(); 
	 
		*pVal = bstHeader.copy(); 
	} 
	catch(...) 
	{ 
		return E_FAIL; 
	} 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::get_Subject(BSTR *pVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
	ATLASSERT(pVal); 
 
	try 
	{ 
		bstr_t bstSubject; 
		bstSubject	= m_cMessage.GetSubject(); 
	 
		*pVal = bstSubject.copy(); 
	} 
	catch(...) 
	{ 
		return E_FAIL; 
	} 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::get_AttachedFiles(BSTR* pVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
	ATLASSERT(pVal); 
 
	try 
	{ 
		*pVal = m_bstAttachedFiles.copy(); 
	} 
	catch(...) 
	{ 
		return E_FAIL; 
	} 
 
	return S_OK; 
} 
 
STDMETHODIMP CPOPLevel::get_Body(BSTR *pVal) 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState()) 
 
	ATLASSERT(pVal); 
		 
	try 
	{ 
		*pVal = m_bstBody.copy(); 
	} 
	catch(...) 
	{ 
		return E_FAIL; 
	} 
 
	return S_OK; 
} 
 
/* 
 * Eucalyptus 
 * by Paul A. Schifferer 
 * 
 * Module: base64.c 
 *   	 Base64 related functions 
 * 
 * Copyright © 1997-9 Isengard Developments 
 * All rights reserved. 
 */ 
 
const CHAR *base64set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 
 
bool CPOPLevel::base64_valid(LONG c) const 
{ 
	LONG x = 0; 
 
	if(c == '=') 
		return(TRUE); 
 
	while(base64set[x]) 
	{ 
		if(c == base64set[x]) 
			return(TRUE); 
		x++; 
	} 
 
	return(FALSE); 
} 
 
CHAR CPOPLevel::base64_get_value(LONG c) const 
{ 
	LONG x = 0; 
 
	while(base64set[x]) 
	{ 
		if(base64set[x] == c) 
			return((CHAR)x); 
		x++; 
	} 
 
	return(-1); 
}