?? pop3.cpp
字號:
// ========================================================
// POP3 Protocol Handler
//
// Design and Implementation by Floris van den Berg
// ========================================================
#pragma warning (disable : 4275)
#pragma warning (disable : 4786)
#include <string>
#include "..\OpenNet.h"
#include "Cabinet.h"
// --------------------------------------------------------
class CPop3Protocol : public IProtocol {
public :
CPop3Protocol();
virtual unsigned long DLL_CALLCONV AddRef();
virtual unsigned long DLL_CALLCONV Release();
virtual HRESULT DLL_CALLCONV QueryInterface(REFIID guid, void **iif);
virtual void DLL_CALLCONV Initialize(TRANSPORT_HANDLE transport);
virtual void DLL_CALLCONV Receive(unsigned char *data, int size);
virtual void DLL_CALLCONV Send(EpAction *action);
virtual void DLL_CALLCONV Reset();
virtual int DLL_CALLCONV GetName(char *name, int size);
virtual int DLL_CALLCONV GetMessageName(int msg, char *name, int size);
private :
int m_ref_count;
TRANSPORT_HANDLE m_transport;
char data[8192];
int data_size;
int data_pos;
};
// --------------------------------------------------------
CPop3Protocol::CPop3Protocol() :
m_ref_count(0),
m_transport(NULL),
data(),
data_size(0),
data_pos(0) {
memset(&data, 0, sizeof(data));
}
unsigned long DLL_CALLCONV
CPop3Protocol::AddRef() {
return ++m_ref_count;
}
unsigned long DLL_CALLCONV
CPop3Protocol::Release() {
int ref_count = --m_ref_count;
if (ref_count == 0)
delete this;
return ref_count;
}
HRESULT DLL_CALLCONV
CPop3Protocol::QueryInterface(REFIID guid, void **iif) {
if (IsEqualGUID(guid, CLSID_POP3_PROTOCOL)) {
AddRef();
*iif = this;
return S_OK;
} else if (IsEqualGUID(guid, GUID_OBJECT)) {
AddRef();
*iif = this;
return S_OK;
}
return E_NOINTERFACE;
}
void DLL_CALLCONV
CPop3Protocol::Initialize(TRANSPORT_HANDLE transport) {
m_transport = transport;
}
void DLL_CALLCONV
CPop3Protocol::Receive(unsigned char *data, int size) {
// copy the data into the buffer
memcpy(data + data_size, data, size);
data_size += size;
// search for 0x0D's. if found we found a valid SMTP reply
int i = 0;
int pos = 0;
// strip any pending 0x0A and 0x0D chars
while (pos < data_size) {
if ((data[pos] != 0x0A) && (data[pos] != 0x0D))
break;
++pos;
}
// search for the next 0x0A or 0x0D
while (pos + i < data_size) {
if ((data[pos + i] == 0x0A) || (data[pos + i] == 0x0D)) {
int char_before_delimiter = (pos + i);
// search a bit further for more 0x0As or 0x0Ds
while (pos + i < data_size) {
if ((data[pos + i] != 0x0A) && (data[pos + i] != 0x0D))
break;
++i;
}
// allocate memory for reply data
char temp[8192];
// allocate an ePlug event
EpEvent pm_event;
pm_event.reference_id = 0;
pm_event.protocol = CLSID_POP3_PROTOCOL;
pm_event.data = (unsigned char *)temp;
// grab the message data
char *dat = (char *)(data + pos);
if ((char_before_delimiter >= 3) && (dat[0] == '+') && (dat[1] == 'O') && (dat[2] == 'K')) {
if (char_before_delimiter - 4 > 0)
memcpy(temp, data + pos + 4, char_before_delimiter - 4);
pm_event.msg = POP3_REPLY_OK;
pm_event.size = char_before_delimiter - 3;
} else if ((char_before_delimiter >= 4) && (dat[0] == '-') && (dat[1] == 'E') && (dat[2] == 'R') && (dat[3] == 'R')) {
if (char_before_delimiter - 5 > 0)
memcpy(temp, data + pos + 5, char_before_delimiter - 5);
pm_event.msg = POP3_REPLY_ERROR;
pm_event.size = char_before_delimiter - 4;
} else if ((char_before_delimiter >= 1) && (dat[0] == '.')) {
pm_event.msg = POP3_REPLY_ENDLIST;
pm_event.data = NULL;
pm_event.size = 0;
} else {
memcpy(temp, data + pos, char_before_delimiter);
pm_event.msg = POP3_REPLY_LISTING;
pm_event.size = char_before_delimiter + 1;
}
// add one extra 0 byte to terminate the string
temp[pm_event.size - 1] = '\0';
// post event
EpDispatchEvent(m_transport, &pm_event);
// move message from queue
memcpy(data, data + i, data_size - i);
data_size -= i;
i = 0;
} else {
++i;
}
}
}
void DLL_CALLCONV
CPop3Protocol::Send(EpAction *action) {
switch(action->msg) {
case POP3_USER :
{
_STL::string s = _STL::string("USER ") + _STL::string((char *)action->data) + _STL::string("\r\n");
EpCompleteAction(m_transport, (unsigned char *)s.c_str(), s.length());
break;
}
case POP3_PASS :
{
_STL::string s = _STL::string("PASS ") + _STL::string((char *)action->data) + _STL::string("\r\n");
EpCompleteAction(m_transport, (unsigned char *)s.c_str(), s.length());
break;
}
case POP3_LIST :
if (action->data) {
char tmp[64];
_STL::string s = _STL::string("LIST ") + _STL::string(itoa(*(DWORD *)action->data, tmp, 10)) + _STL::string("\r\n");
EpCompleteAction(m_transport, (unsigned char *)s.c_str(), s.length());
} else {
EpCompleteAction(m_transport, (unsigned char *)"LIST\r\n", 6);
}
break;
case POP3_RETR :
{
char tmp[64];
_STL::string s = _STL::string("RETR ") + _STL::string(itoa(*(DWORD *)action->data, tmp, 10)) + _STL::string("\r\n");
EpCompleteAction(m_transport, (unsigned char *)s.c_str(), s.length());
break;
}
case POP3_DELE :
{
char tmp[64];
_STL::string s = _STL::string("DELE ") + _STL::string(itoa(*(DWORD *)action->data, tmp, 10)) + _STL::string("\r\n");
EpCompleteAction(m_transport, (unsigned char *)s.c_str(), s.length());
break;
}
case POP3_UIDL :
if (action->data) {
char tmp[64];
_STL::string s = _STL::string("UIDL ") + _STL::string(itoa(*(DWORD *)action->data, tmp, 10)) + _STL::string("\r\n");
EpCompleteAction(m_transport, (unsigned char *)s.c_str(), s.length());
} else {
EpCompleteAction(m_transport, (unsigned char *)"UIDL\r\n", 6);
}
break;
case POP3_NOOP :
EpCompleteAction(m_transport, (unsigned char *)"NOOP\r\n", 6);
break;
case POP3_STAT :
EpCompleteAction(m_transport, (unsigned char *)"STAT\r\n", 6);
break;
case POP3_RSET :
EpCompleteAction(m_transport, (unsigned char *)"RSET\r\n", 6);
break;
case POP3_TOP :
{
Pop3Top *top = (Pop3Top *)action->data;
char tmp1[64];
char tmp2[64];
_STL::string s = _STL::string("TOP ") + _STL::string(itoa(top->message_id, tmp1, 10)) + _STL::string(" ") + _STL::string(itoa(top->max_lines, tmp2, 10)) + _STL::string("\r\n");
EpCompleteAction(m_transport, (unsigned char *)s.c_str(), s.length());
break;
}
case POP3_QUIT :
EpCompleteAction(m_transport, (unsigned char *)"QUIT\r\n", 6);
break;
};
}
void DLL_CALLCONV
CPop3Protocol::Reset() {
data_size = 0;
data_pos = 0;
memset(&data, 0, sizeof(data));
}
int DLL_CALLCONV
CPop3Protocol::GetName(char *name, int size) {
if (size >= 5)
strcpy(name, "POP3");
return 5;
}
int DLL_CALLCONV
CPop3Protocol::GetMessageName(int msg, char *name, int size) {
return 0;
}
// --------------------------------------------------------
// Instantation function
// --------------------------------------------------------
static HRESULT DLL_CALLCONV
Pop3ProtocolCreate(void **iif) {
CPop3Protocol *object = new CPop3Protocol;
if (object) {
object->AddRef();
*iif = object;
return S_OK;
}
return E_FAIL;
}
// --------------------------------------------------------
// Discover function
// --------------------------------------------------------
void DLL_CALLCONV
Pop3ProtocolInitialize() {
EpRegisterProtocol(CLSID_POP3_PROTOCOL, Pop3ProtocolCreate);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -