?? pop3.cpp
字號:
//Must be connected to perform a "LIST"
ASSERT(m_bConnected);
//if we haven't executed the STAT command then do it now
int nNumberOfMails = m_nNumberOfMails;
int nTotalMailSize;
if (!m_bStatRetrieved)
{
if (!Statistics(nNumberOfMails, nTotalMailSize))
return FALSE;
else
m_bStatRetrieved = TRUE;
}
//Send the LIST command
char sBuf[10];
strcpy(sBuf, "LIST\r\n");
int nCmdLength = strlen(sBuf);
if (!m_Pop.Send(sBuf, nCmdLength))
{
TRACE(_T("Failed to send the LIST command to the POP3 server\n"));
return FALSE;
}
//And check the response
m_bListRetrieved = ReadListResponse(nNumberOfMails);
return m_bListRetrieved;
}
BOOL CPop3Connection::UIDL()
{
//Must be connected to perform a "UIDL"
ASSERT(m_bConnected);
//if we haven't executed the STAT command then do it now
int nNumberOfMails = m_nNumberOfMails;
int nTotalMailSize;
if (!m_bStatRetrieved)
{
if (!Statistics(nNumberOfMails, nTotalMailSize))
return FALSE;
else
m_bStatRetrieved = TRUE;
}
//Send the UIDL command
char sBuf[10];
strcpy(sBuf, "UIDL\r\n");
int nCmdLength = strlen(sBuf);
if (!m_Pop.Send(sBuf, nCmdLength))
{
TRACE(_T("Failed to send the UIDL command to the POP3 server\n"));
return FALSE;
}
//And check the response
m_bUIDLRetrieved = ReadUIDLResponse(nNumberOfMails);
return m_bUIDLRetrieved;
}
BOOL CPop3Connection::Reset()
{
//Must be connected to perform a "RSET"
ASSERT(m_bConnected);
//Send the RSET command
char sBuf[10];
strcpy(sBuf, "RSET\r\n");
int nCmdLength = strlen(sBuf);
if (!m_Pop.Send(sBuf, nCmdLength))
{
TRACE(_T("Failed to send the RSET command to the POP3 server\n"));
return FALSE;
}
//And check the command
return ReadCommandResponse();
}
BOOL CPop3Connection::Noop()
{
//Must be connected to perform a "NOOP"
ASSERT(m_bConnected);
//Send the NOOP command
char sBuf[10];
strcpy(sBuf, "NOOP\r\n");
int nCmdLength = strlen(sBuf);
if (!m_Pop.Send(sBuf, nCmdLength))
{
TRACE(_T("Failed to send the NOOP command to the POP3 server\n"));
return FALSE;
}
//And check the response
return ReadCommandResponse();
}
BOOL CPop3Connection::Retrieve(int nMsg, CPop3Message& message)
{
//Must be connected to retrieve a message
ASSERT(m_bConnected);
//work out the size of the message to retrieve
DWORD dwSize;
if (GetMessageSize(nMsg, dwSize))
{
//Send the RETR command
char sBuf[20];
sprintf(sBuf, "RETR %d\r\n", nMsg);
int nCmdLength = strlen(sBuf);
if (!m_Pop.Send(sBuf, nCmdLength))
{
TRACE(_T("Failed to send the RETR command to the POP3 server\n"));
return FALSE;
}
//And check the command
return ReadReturnResponse(message, dwSize);
}
else
return FALSE;
}
BOOL CPop3Connection::GetMessageHeader(int nMsg, CPop3Message& message)
{
// Must be connected to retrieve a message
ASSERT(m_bConnected);
// make sure the message actually exists
DWORD dwSize;
if (GetMessageSize(nMsg, dwSize))
{
// Send the TOP command
char sBuf[16];
sprintf(sBuf, "TOP %d 0\r\n", nMsg);
int nCmdLength = strlen(sBuf);
if (!m_Pop.Send(sBuf, nCmdLength))
{
TRACE(_T("Failed to send the TOP command to the POP3 server\n"));
return FALSE;
}
// And check the command
return ReadReturnResponse(message, dwSize);
}
else
return FALSE;
}
BOOL CPop3Connection::GetMessageTop(int nMsg, int rawCount, CPop3Message& message)
{
// Must be connected to retrieve a message
ASSERT(m_bConnected);
// make sure the message actually exists
DWORD dwSize;
if (GetMessageSize(nMsg, dwSize))
{
// Send the TOP command
char sBuf[16];
sprintf(sBuf, "TOP %d %d\r\n", nMsg, rawCount);
int nCmdLength = strlen(sBuf);
if (!m_Pop.Send(sBuf, nCmdLength))
{
TRACE(_T("Failed to send the TOP command to the POP3 server\n"));
return FALSE;
}
// And check the command
return ReadReturnResponse(message, dwSize);
}
else
return FALSE;
}
BOOL CPop3Connection::ReadCommandResponse()
{
LPSTR pszOverFlowBuffer = NULL;
char sBuf[1000];
BOOL bSuccess = ReadResponse(sBuf, 1000, "\r\n", &pszOverFlowBuffer);
if (pszOverFlowBuffer)
delete [] pszOverFlowBuffer;
return bSuccess;
}
LPSTR CPop3Connection::GetFirstCharInResponse(LPSTR pszData) const
{
while ((*pszData != '\n') && *pszData)
++pszData;
//skip over the "\n" onto the next line
if (*pszData)
++pszData;
return pszData;
}
BOOL CPop3Connection::ReadResponse(LPSTR pszBuffer, int nInitialBufSize, LPSTR pszTerminator, LPSTR* ppszOverFlowBuffer, int nGrowBy)
{
ASSERT(ppszOverFlowBuffer); //Must have a valid string pointer
ASSERT(*ppszOverFlowBuffer == NULL); //Initially it must point to a NULL string
//must have been created first
ASSERT(m_bConnected);
//The local variables which will receive the data
LPSTR pszRecvBuffer = pszBuffer;
int nBufSize = nInitialBufSize;
//retrieve the reponse using until we
//get the terminator or a timeout occurs
BOOL bFoundTerminator = FALSE;
int nReceived = 0;
DWORD dwStartTicks = ::GetTickCount();
while (!bFoundTerminator)
{
//Has the timeout occured
if ((::GetTickCount() - dwStartTicks) > m_dwTimeout)
{
pszRecvBuffer[nReceived] = '\0';
SetLastError(WSAETIMEDOUT);
m_sLastCommandResponse = pszRecvBuffer; //Hive away the last command reponse
return FALSE;
}
//check the socket for readability
BOOL bReadible;
if (!m_Pop.IsReadible(bReadible))
{
pszRecvBuffer[nReceived] = '\0';
m_sLastCommandResponse = pszRecvBuffer; //Hive away the last command reponse
return FALSE;
}
else if (!bReadible) //no data to receive, just loop around
{
Sleep(250); //Sleep for a while before we loop around again
continue;
}
//receive the data from the socket
int nBufRemaining = nBufSize-nReceived-1; //Allows allow one space for the NULL terminator
if (nBufRemaining<0)
nBufRemaining = 0;
int nData = m_Pop.Receive(pszRecvBuffer+nReceived, nBufRemaining);
//Reset the idle timeout if data was received
if (nData)
{
dwStartTicks = ::GetTickCount();
//Increment the count of data received
nReceived += nData;
}
//If an error occurred receiving the data
if (nData == SOCKET_ERROR)
{
//NULL terminate the data received
if (pszRecvBuffer)
pszBuffer[nReceived] = '\0';
m_sLastCommandResponse = pszRecvBuffer; //Hive away the last command reponse
return FALSE;
}
else
{
//NULL terminate the data received
if (pszRecvBuffer)
pszRecvBuffer[nReceived] = '\0';
if (nBufRemaining-nData == 0) //No space left in the current buffer
{
//Allocate the new receive buffer
nBufSize += nGrowBy; //Grow the buffer by the specified amount
LPSTR pszNewBuf = new char[nBufSize];
//copy the old contents over to the new buffer and assign
//the new buffer to the local variable used for retreiving
//from the socket
if (pszRecvBuffer)
strcpy(pszNewBuf, pszRecvBuffer);
pszRecvBuffer = pszNewBuf;
//delete the old buffer if it was allocated
if (*ppszOverFlowBuffer)
delete [] *ppszOverFlowBuffer;
//Remember the overflow buffer for the next time around
*ppszOverFlowBuffer = pszNewBuf;
}
}
//Check to see if the terminator character(s) have been found
bFoundTerminator = (strstr(pszRecvBuffer, pszTerminator) != NULL);
}
//Remove the terminator from the response data
pszRecvBuffer[nReceived - strlen(pszTerminator)] = '\0';
//determine if the response is an error
BOOL bSuccess = (strnicmp(pszRecvBuffer,"+OK", 3) == 0);
if (!bSuccess)
{
SetLastError(WSAEPROTONOSUPPORT);
m_sLastCommandResponse = pszRecvBuffer; //Hive away the last command reponse
}
return bSuccess;
}
BOOL CPop3Connection::ReadReturnResponse(CPop3Message& message, DWORD dwSize)
{
//Must be connected to perform a "RETR"
ASSERT(m_bConnected);
//Retrieve the message body
LPSTR pszOverFlowBuffer = NULL;
int nSize = dwSize + 100;
char* sBuf = new char[nSize];
char* sMessageBuf = sBuf;
if (!ReadResponse(sBuf, nSize, "\r\n.\r\n", &pszOverFlowBuffer, 32000))
{
delete [] sBuf;
if (pszOverFlowBuffer)
delete [] pszOverFlowBuffer;
TRACE(_T("Error retrieving the RETR response"));
return FALSE;
}
if (pszOverFlowBuffer)
sMessageBuf = pszOverFlowBuffer;
//determine if the response is an error
if (strnicmp(sMessageBuf,"+OK", 3) != 0)
{
delete [] sBuf;
if (pszOverFlowBuffer)
delete [] pszOverFlowBuffer;
SetLastError(WSAEPROTONOSUPPORT);
TRACE(_T("POP3 server did not respond correctly to the RETR response\n"));
return FALSE;
}
else
{
//remove the first line which contains the +OK from the message
char* pszFirst = GetFirstCharInResponse(sMessageBuf);
VERIFY(pszFirst);
//transfer the message contents to the message class
int nMessageSize = sMessageBuf - pszFirst + strlen(sMessageBuf);
// Do we already have memory allocated? If so, destroy it!
if (message.m_pszMessage)
{
delete [] message.m_pszMessage;
message.m_pszMessage = NULL;
}
message.m_pszMessage = new char[nMessageSize + 1];
memcpy(message.m_pszMessage, pszFirst, nMessageSize);
message.m_pszMessage[nMessageSize] = '\0';
}
delete [] sBuf;
if (pszOverFlowBuffer)
delete [] pszOverFlowBuffer;
return TRUE;
}
BOOL CPop3Connection::ReadListResponse(int nNumberOfMails)
{
//Must be connected to perform a "LIST"
ASSERT(m_bConnected);
//retrieve the reponse
LPSTR pszOverFlowBuffer = NULL;
int nSize = 14 * nNumberOfMails + 100;
char* sBuf = new char[nSize];
char* sMessageBuf = sBuf;
if (!ReadResponse(sBuf, nSize, "\r\n.\r\n", &pszOverFlowBuffer))
{
delete [] sBuf;
if (pszOverFlowBuffer)
delete [] pszOverFlowBuffer;
TRACE(_T("Error retrieving the LIST response from the POP3 server"));
return FALSE;
}
if (pszOverFlowBuffer)
sMessageBuf = pszOverFlowBuffer;
//determine if the response is an error
if (strnicmp(sMessageBuf,"+OK", 3) != 0)
{
delete [] sBuf;
if (pszOverFlowBuffer)
delete [] pszOverFlowBuffer;
SetLastError(WSAEPROTONOSUPPORT);
TRACE(_T("POP3 server did not respond correctly to the LIST response\n"));
return FALSE;
}
else
{
//Retrieve the message sizes and put them
//into the m_msgSizes array
m_msgSizes.RemoveAll();
m_msgSizes.SetSize(0, nNumberOfMails);
//then parse the LIST response
char* pszSize = GetFirstCharInResponse(sMessageBuf);
VERIFY(pszSize);
for (; *pszSize != '.'; pszSize++)
if (*pszSize == '\t' || *pszSize == ' ')
m_msgSizes.Add(atoi(pszSize));
}
delete [] sBuf;
if (pszOverFlowBuffer)
delete [] pszOverFlowBuffer;
return TRUE;
}
BOOL CPop3Connection::ReadUIDLResponse(int nNumberOfMails)
{
//Must be connected to perform a "LIST"
ASSERT(m_bConnected);
//retrieve the reponse
LPSTR pszOverFlowBuffer = NULL;
int nSize = 14 * nNumberOfMails + 100;
char* sBuf = new char[nSize];
char* sMessageBuf = sBuf;
if (!ReadResponse(sBuf, nSize, "\r\n.\r\n", &pszOverFlowBuffer))
{
delete [] sBuf;
if (pszOverFlowBuffer)
delete [] pszOverFlowBuffer;
TRACE(_T("Error retrieving the UIDL response from the POP3 server"));
return FALSE;
}
if (pszOverFlowBuffer)
sMessageBuf = pszOverFlowBuffer;
//determine if the response is an error
if (strnicmp(sMessageBuf,"+OK", 3) != 0)
{
delete [] sBuf;
if (pszOverFlowBuffer)
delete [] pszOverFlowBuffer;
SetLastError(WSAEPROTONOSUPPORT);
TRACE(_T("POP3 server did not respond correctly to the UIDL response\n"));
return FALSE;
}
else
{
//Retrieve the message ID's and put them
//into the m_msgIDs array
m_msgIDs.RemoveAll();
m_msgIDs.SetSize(0, nNumberOfMails);
//then parse the UIDL response
char* pszSize = GetFirstCharInResponse(sMessageBuf);
VERIFY(pszSize);
for (; *pszSize != '.'; pszSize++)
{
char* pszBegin = pszSize;
while (*pszSize != '\n' && *pszSize != '.')
{
++pszSize;
}
if (*pszSize == '.')
continue;
char sMsg[15];
char sID[1000];
*pszSize = '\0';
sscanf(pszBegin, "%s %s", sMsg, sID);
m_msgIDs.Add(CString(sID));
}
}
delete [] sBuf;
if (pszOverFlowBuffer)
delete [] pszOverFlowBuffer;
return TRUE;
}
BOOL CPop3Connection::ReadStatResponse(int& nNumberOfMails, int& nTotalMailSize)
{
//Must be connected to perform a "STAT"
ASSERT(m_bConnected);
//retrieve the reponse
LPSTR pszOverFlowBuffer = NULL;
char sBuf[100];
char* sMessageBuf = sBuf;
if (!ReadResponse(sBuf, 100, "\r\n", &pszOverFlowBuffer))
{
if (pszOverFlowBuffer)
delete [] pszOverFlowBuffer;
TRACE(_T("Error retrieving the STAT response from the POP3 server"));
return FALSE;
}
if (pszOverFlowBuffer)
sMessageBuf = pszOverFlowBuffer;
//determine if the response is an error
if (strncmp(sMessageBuf,"+OK", 3) != 0)
{
TRACE(_T("POP3 server did not respond correctly to the STAT response\n"));
return FALSE;
}
else
{
//Parse out the Number of Mails and Total mail size values
BOOL bGetNumber = TRUE;
for (char* pszNum=sMessageBuf; *pszNum!='\0'; pszNum++)
{
if (*pszNum=='\t' || *pszNum==' ')
{
if (bGetNumber)
{
nNumberOfMails = atoi(pszNum);
m_nNumberOfMails = nNumberOfMails;
bGetNumber = FALSE;
}
else
{
nTotalMailSize = atoi(pszNum);
return TRUE;
}
}
}
}
if (pszOverFlowBuffer)
delete [] pszOverFlowBuffer;
return FALSE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -