?? mail.cpp
字號:
#pragma warning (disable : 4786)
#include <list>
#include <string>
#include <vector>
#include "..\ETransport.h"
#include "mail.h"
#include "MailDecoder.h"
// --------------------------------------------------------
static Protocol *s_pop3_protocol;
static Protocol *s_smtp_protocol;
// --------------------------------------------------------
// Mail Protocol data
// --------------------------------------------------------
/*
struct QueueData {
MailReceiveEvents m_event;
int m_count;
};
struct MailData {
PLUG_HANDLE m_plug_handle;
void *m_pop3_handle;
std::list<QueueData> m_event_queue;
std::string username;
std::string password;
std::string mail_content;
MailMessageCount message_count;
std::vector<MailMessageListEntry> message_list_entries;
};
*/
// --------------------------------------------------------
// These functions monitors all events being passed from
// the pop3 protocol to the user and vice versa.
// --------------------------------------------------------
/*
static bool DLL_CALLCONV
FilterLogin(void *data, PLUG_HANDLE plug, EpEvent *event) {
MailData *mail = (MailData *)data;
// cancel any action we were doing when an error occurs on the socket
if (IsEqualGUID(event->protocol, CLSID_PROTOCOL_SYSTEM)) {
switch(event->msg) {
case SYSTEM_NOT_CONNECTED :
case SYSTEM_DISCONNECTED :
case SYSTEM_IO_ERROR :
EpRemoveEventFilter(mail->m_plug_handle, FilterLogin);
mail->m_event_queue.clear();
break;
};
} else if (IsEqualGUID(event->protocol, CLSID_POP3_PROTOCOL)) {
EpEvent new_event;
new_event.reference_id = 0;
new_event.timeout = 0;
mail->m_event_queue.front().m_count++;
switch(event->msg) {
case POP3_REPLY_OK :
switch(mail->m_event_queue.front().m_count) {
case 1 :
new_event.protocol = CLSID_POP3_PROTOCOL;
new_event.msg = POP3_PASS;
new_event.data = (unsigned char *)mail->password.c_str();
new_event.size = mail->password.length() + 1;
EpSendEvent(plug, &new_event);
return false;
case 2 :
{
new_event.protocol = CLSID_POP3_PROTOCOL;
new_event.msg = POP3_LIST;
new_event.data = 0;
new_event.size = 0;
EpDispatchEvent(plug, &new_event);
FILE *file = fopen("log.txt", "a+");
fprintf(file, "sending out LIST\n");
fclose(file);
return false;
}
case 3 :
{
std::string message_count;
int i = 0;
while ((i < event->size) && (event->data[i] != ' '))
message_count += event->data[i++];
if (atoi(message_count.c_str()) == 0) {
mail->m_event_queue.pop_front();
new_event.protocol = CLSID_MAILRECV_PROTOCOL;
new_event.msg = MAILRECV_LOGIN;
new_event.data = 0;
new_event.size = 0;
EpDispatchEvent(plug, &new_event);
}
mail->message_list_entries.clear();
return false;
}
};
return true;
case POP3_REPLY_LISTING :
{
std::string message_count;
std::string message_octets;
int i = 0;
while ((i < event->size) && (event->data[i] != ' '))
message_count += event->data[i++];
while ((i < event->size) && (event->data[i] == ' '))
++i;
while (i < event->size)
message_octets += event->data[i++];
MailMessageListEntry entry;
entry.message_id = atoi(message_count.c_str());
entry.octets = atoi(message_octets.c_str());
mail->message_list_entries.push_back(entry);
return false;
}
case POP3_REPLY_ENDLIST :
{
mail->m_event_queue.pop_front();
// store the number of found messages in the struct
mail->message_count.message_count = mail->message_list_entries.size();
// copy the message data
int size = sizeof(int) + mail->message_list_entries.size() * sizeof(MailMessageListEntry);
unsigned char *data = new unsigned char[size];
memcpy(data, &mail->message_count, sizeof(int));
for (int i = 0; i < mail->message_list_entries.size(); ++i)
memcpy(data + sizeof(int) + i * sizeof(MailMessageListEntry), &mail->message_list_entries[i], sizeof(MailMessageListEntry));
// send an event to the user
new_event.protocol = CLSID_MAILRECV_PROTOCOL;
new_event.msg = MAILRECV_LOGIN;
new_event.data = 0;
new_event.size = 0;
EpDispatchEvent(plug, &new_event);
// delete the allocated data
delete [] data;
return false;
}
case POP3_REPLY_ERROR :
mail->m_event_queue.pop_front();
new_event.protocol = CLSID_MAILRECV_PROTOCOL;
new_event.msg = MAILRECV_LOGIN_FAILED;
new_event.data = event->data;
new_event.size = event->size;
EpDispatchEvent(plug, &new_event);
return false;
};
}
return true;
}
static bool DLL_CALLCONV
FilterMessageCount(void *data, PLUG_HANDLE plug, EpEvent *event) {
MailData *mail = (MailData *)data;
if (IsEqualGUID(event->protocol, CLSID_PROTOCOL_SYSTEM)) {
switch(event->msg) {
case SYSTEM_NOT_CONNECTED :
case SYSTEM_DISCONNECTED :
case SYSTEM_IO_ERROR :
EpRemoveEventFilter(mail->m_plug_handle, FilterMessageCount);
mail->m_event_queue.clear();
break;
};
} else if (IsEqualGUID(event->protocol, CLSID_POP3_PROTOCOL)) {
EpEvent new_event;
new_event.reference_id = 0;
new_event.timeout = 0;
switch(event->msg) {
case POP3_REPLY_OK :
{
mail->m_event_queue.pop_front();
std::string message_count;
std::string message_octets;
int length = strlen((char *)event->data);
int i = 0;
while ((i < length) && (event->data[i] != ' '))
message_count += event->data[i++];
while ((i < length) && (event->data[i] == ' '))
++i;
while (i < length)
message_octets += event->data[i++];
MailMessageCount count;
count.message_count = atoi(message_count.c_str());
count.octets = atoi(message_octets.c_str());
new_event.protocol = CLSID_MAILRECV_PROTOCOL;
new_event.msg = MAILRECV_GETMESSAGECOUNT;
new_event.data = (unsigned char *)&count;
new_event.size = sizeof(count);
EpDispatchEvent(plug, &new_event);
return false;
}
case POP3_REPLY_ERROR :
mail->m_event_queue.pop_front();
new_event.protocol = CLSID_MAILRECV_PROTOCOL;
new_event.msg = MAILRECV_GETMESSAGECOUNT_FAILED;
new_event.data = event->data;
new_event.size = event->size;
EpDispatchEvent(plug, &new_event);
return true;
};
}
return true;
}
static bool DLL_CALLCONV
FilterDeleteMessage(void *data, PLUG_HANDLE plug, EpEvent *event) {
MailData *mail = (MailData *)data;
// cancel any action we were doing when an error occurs on the socket
if (IsEqualGUID(event->protocol, CLSID_PROTOCOL_SYSTEM)) {
switch(event->msg) {
case SYSTEM_NOT_CONNECTED :
case SYSTEM_DISCONNECTED :
case SYSTEM_IO_ERROR :
EpRemoveEventFilter(mail->m_plug_handle, FilterDeleteMessage);
mail->m_event_queue.clear();
break;
};
// continue a batch send when this is a pop3 protocol
} else if (IsEqualGUID(event->protocol, CLSID_POP3_PROTOCOL)) {
EpEvent new_event;
new_event.reference_id = 0;
new_event.timeout = 0;
switch(event->msg) {
case POP3_REPLY_OK :
mail->m_event_queue.pop_front();
new_event.protocol = CLSID_MAILRECV_PROTOCOL;
new_event.msg = MAILRECV_DELETEMESSAGE;
new_event.data = NULL;
new_event.size = 0;
EpDispatchEvent(plug, &new_event);
return false;
case POP3_REPLY_ERROR :
mail->m_event_queue.pop_front();
new_event.protocol = CLSID_MAILRECV_PROTOCOL;
new_event.msg = MAILRECV_DELETEMESSAGE_FAILED;
new_event.data = event->data;
new_event.size = event->size;
EpDispatchEvent(plug, &new_event);
return false;
};
}
return true;
}
static bool DLL_CALLCONV
FilterGetMessage(void *data, PLUG_HANDLE plug, EpEvent *event) {
MailData *mail = (MailData *)data;
// cancel any action we were doing when an error occurs on the socket
if (IsEqualGUID(event->protocol, CLSID_PROTOCOL_SYSTEM)) {
switch(event->msg) {
case SYSTEM_NOT_CONNECTED :
case SYSTEM_DISCONNECTED :
case SYSTEM_IO_ERROR :
EpRemoveEventFilter(mail->m_plug_handle, FilterGetMessage);
mail->m_event_queue.clear();
break;
};
} else if (IsEqualGUID(event->protocol, CLSID_POP3_PROTOCOL)) {
EpEvent new_event;
new_event.reference_id = 0;
new_event.timeout = 0;
switch(event->msg) {
case POP3_REPLY_LISTING :
if (!mail->mail_content.empty())
mail->mail_content += std::string("\r\n");
mail->mail_content += std::string((char *)event->data);
return false;
case POP3_REPLY_ENDLIST :
{
mail->m_event_queue.pop_front();
new_event.protocol = CLSID_MAILRECV_PROTOCOL;
new_event.msg = MAILRECV_GETMESSAGE;
new_event.data = (unsigned char *)mail->mail_content.c_str();
new_event.size = mail->mail_content.length() + 1;
MailDecoder decoder;
decoder.open(mail->mail_content);
EpDispatchEvent(plug, &new_event);
return false;
}
case POP3_REPLY_ERROR :
mail->m_event_queue.pop_front();
new_event.protocol = CLSID_MAILRECV_PROTOCOL;
new_event.msg = MAILRECV_GETMESSAGE_FAILED;
new_event.data = event->data;
new_event.size = event->size;
EpDispatchEvent(plug, &new_event);
return false;
};
}
return true;
}
// --------------------------------------------------------
static void *DLL_CALLCONV
ProtocolCreate(PLUG_HANDLE plug) {
MailData *mail = new MailData;
mail->m_plug_handle = plug;
mail->m_pop3_handle = s_pop3_protocol->create(plug);
return mail;
}
static bool DLL_CALLCONV
ProtocolReceive(void *self, const unsigned char *data, int size) {
MailData *mail = (MailData *)self;
return s_pop3_protocol->receive(mail->m_pop3_handle, data, size);
}
static bool DLL_CALLCONV
ProtocolSend(void *self, EpEvent *event) {
MailData *mail = (MailData *)self;
if (IsEqualGUID(event->protocol, CLSID_MAILRECV_PROTOCOL)) {
EpEvent new_event;
new_event.protocol = CLSID_POP3_PROTOCOL;
new_event.reference_id = 0;
new_event.timeout = 0;
QueueData data;
data.m_count = 0;
data.m_event = (MailReceiveEvents)event->msg;
switch(event->msg) {
case MAILRECV_LOGIN :
{
EpInstallEventFilter(mail->m_plug_handle, FilterLogin, mail);
mail->m_event_queue.push_back(data);
MailRecvLogin *login = (MailRecvLogin *)event->data;
mail->username = login->username;
mail->password = login->password;
new_event.msg = POP3_USER;
new_event.data = (unsigned char *)mail->username.c_str();
new_event.size = mail->username.length() + 1;
s_pop3_protocol->send(mail->m_pop3_handle, &new_event);
return true;
}
case MAILRECV_GETMESSAGE :
EpInstallEventFilter(mail->m_plug_handle, FilterGetMessage, mail);
mail->m_event_queue.push_back(data);
mail->mail_content.erase();
new_event.msg = POP3_RETR;
new_event.data = event->data;
new_event.size = event->size;
s_pop3_protocol->send(mail->m_pop3_handle, &new_event);
return true;
case MAILRECV_GETMESSAGECOUNT :
EpInstallEventFilter(mail->m_plug_handle, FilterMessageCount, mail);
mail->m_event_queue.push_back(data);
new_event.msg = POP3_STAT;
new_event.data = event->data;
new_event.size = event->size;
s_pop3_protocol->send(mail->m_pop3_handle, &new_event);
return true;
case MAILRECV_DELETEMESSAGE :
EpInstallEventFilter(mail->m_plug_handle, FilterDeleteMessage, mail);
mail->m_event_queue.push_back(data);
new_event.msg = POP3_DELE;
new_event.data = event->data;
new_event.size = event->size;
s_pop3_protocol->send(mail->m_pop3_handle, &new_event);
return true;
}
return false;
}
return s_pop3_protocol->send(mail->m_pop3_handle, event);
}
static void DLL_CALLCONV
ProtocolDestroy(void *self) {
MailData *mail = (MailData *)self;
s_pop3_protocol->destroy(mail->m_pop3_handle);
delete mail;
}
*/
// --------------------------------------------------------
SMTP_API unsigned int DLL_CALLCONV
EpProtocolCount() {
return 3;
}
SMTP_API CLSID DLL_CALLCONV
EpProtocolInit(unsigned int count, Protocol *protocol) {
switch(count) {
case 0 : return EpIRCProtocolInit(protocol);
case 1 : return EpSMTPProtocolInit(protocol);
case 2 : return EpPOP3ProtocolInit(protocol);
};
return CLSID_NULL_PROTOCOL;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -