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);
}