?? pop3.cpp
字號:
// ========================================================
// ePlug POP3 protocol implementation
//
// Design and implementation by:
// - Floris van den Berg
// ========================================================
#include <string>
#include "..\ETransport.h"
#include "mail.h"
// --------------------------------------------------------
struct ProtocolData {
TRANSPORT_HANDLE plug;
char data[8192];
int data_size;
int data_pos;
};
// --------------------------------------------------------
static void *DLL_CALLCONV
ProtocolCreate(TRANSPORT_HANDLE plug) {
ProtocolData *prot_data = new ProtocolData;
memset(prot_data, 0, sizeof(ProtocolData));
prot_data->plug = plug;
return prot_data;
}
static bool DLL_CALLCONV
ProtocolReceive(void *self, unsigned char *data, int size) {
ProtocolData *prot_data = (ProtocolData *)self;
// copy the data into the buffer
memcpy(prot_data->data + prot_data->data_size, data, size);
prot_data->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 < prot_data->data_size) {
if ((prot_data->data[pos] != 0x0A) && (prot_data->data[pos] != 0x0D))
break;
++pos;
}
// search for the next 0x0A or 0x0D
while (pos + i < prot_data->data_size) {
if ((prot_data->data[pos + i] == 0x0A) || (prot_data->data[pos + i] == 0x0D)) {
int char_before_delimiter = (pos + i);
// search a bit further for more 0x0As or 0x0Ds
while (pos + i < prot_data->data_size) {
if ((prot_data->data[pos + i] != 0x0A) && (prot_data->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 = prot_data->data + pos;
if ((char_before_delimiter >= 3) && (dat[0] == '+') && (dat[1] == 'O') && (dat[2] == 'K')) {
if (char_before_delimiter - 4 > 0)
memcpy(temp, prot_data->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, prot_data->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, prot_data->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(prot_data->plug, &pm_event);
// move message from queue
memcpy(prot_data->data, prot_data->data + i, prot_data->data_size - i);
prot_data->data_size -= i;
i = 0;
} else {
++i;
}
}
return true;
}
static bool DLL_CALLCONV
ProtocolSend(void *self, EpAction *action){
ProtocolData *prot_data = (ProtocolData *)self;
switch(action->msg) {
case POP3_USER :
{
std::string s = std::string("USER ") + std::string((char *)action->data) + std::string("\r\n");
EpCompleteAction(prot_data->plug, (unsigned char *)s.c_str(), s.length());
break;
}
case POP3_PASS :
{
std::string s = std::string("PASS ") + std::string((char *)action->data) + std::string("\r\n");
EpCompleteAction(prot_data->plug, (unsigned char *)s.c_str(), s.length());
break;
}
case POP3_LIST :
if (action->data) {
char tmp[64];
std::string s = std::string("LIST ") + std::string(itoa(*(DWORD *)action->data, tmp, 10)) + std::string("\r\n");
EpCompleteAction(prot_data->plug, (unsigned char *)s.c_str(), s.length());
} else {
EpCompleteAction(prot_data->plug, (unsigned char *)"LIST\r\n", 6);
}
break;
case POP3_RETR :
{
char tmp[64];
std::string s = std::string("RETR ") + std::string(itoa(*(DWORD *)action->data, tmp, 10)) + std::string("\r\n");
EpCompleteAction(prot_data->plug, (unsigned char *)s.c_str(), s.length());
break;
}
case POP3_DELE :
{
char tmp[64];
std::string s = std::string("DELE ") + std::string(itoa(*(DWORD *)action->data, tmp, 10)) + std::string("\r\n");
EpCompleteAction(prot_data->plug, (unsigned char *)s.c_str(), s.length());
break;
}
case POP3_UIDL :
if (action->data) {
char tmp[64];
std::string s = std::string("UIDL ") + std::string(itoa(*(DWORD *)action->data, tmp, 10)) + std::string("\r\n");
EpCompleteAction(prot_data->plug, (unsigned char *)s.c_str(), s.length());
} else {
EpCompleteAction(prot_data->plug, (unsigned char *)"UIDL\r\n", 6);
}
break;
case POP3_NOOP :
EpCompleteAction(prot_data->plug, (unsigned char *)"NOOP\r\n", 6);
break;
case POP3_STAT :
EpCompleteAction(prot_data->plug, (unsigned char *)"STAT\r\n", 6);
break;
case POP3_RSET :
EpCompleteAction(prot_data->plug, (unsigned char *)"RSET\r\n", 6);
break;
case POP3_TOP :
{
Pop3Top *top = (Pop3Top *)action->data;
char tmp1[64];
char tmp2[64];
std::string s = std::string("TOP ") + std::string(itoa(top->message_id, tmp1, 10)) + std::string(" ") + std::string(itoa(top->max_lines, tmp2, 10)) + std::string("\r\n");
EpCompleteAction(prot_data->plug, (unsigned char *)s.c_str(), s.length());
break;
}
case POP3_QUIT :
EpCompleteAction(prot_data->plug, (unsigned char *)"QUIT\r\n", 6);
break;
};
return true;
}
static void DLL_CALLCONV
ProtocolDestroy(void *self) {
delete (ProtocolData *)self;
}
// --------------------------------------------------------
SMTP_API CLSID DLL_CALLCONV
EpPOP3ProtocolInit(Protocol *protocol) {
protocol->create = ProtocolCreate;
protocol->destroy = ProtocolDestroy;
protocol->receive = ProtocolReceive;
protocol->send = ProtocolSend;
return CLSID_POP3_PROTOCOL;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -