📄 mail.cpp
字号:
#pragma warning (disable : 4786)
#include <list>
#include <string>
#include <vector>
#include "..\OpenNet.h"
#include "..\OpenNetExtensions.h"
#include "Cabinet.h"
#include "MailDecoder.h"
// ------------------------------------------------------
// Internal structures
// ------------------------------------------------------
enum EnumCommandType {
ECT_LOGIN = 0,
};
struct Command {
EnumCommandType type;
};
struct CommandLogin : public Command {
int count;
};
// ------------------------------------------------------
// DLL Initialization
// ------------------------------------------------------
class CPop3Session : public IPop3Session {
public :
CPop3Session();
~CPop3Session();
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, Connection *connection);
virtual int DLL_CALLCONV GetProtocolCount();
virtual void DLL_CALLCONV GetProtocols(GUID *guid);
virtual bool DLL_CALLCONV Receive(EpEvent *event);
public :
virtual void DLL_CALLCONV Login(const char *username, const char *password);
private :
virtual bool DLL_CALLCONV ReceiveLogin(CommandLogin *command, EpEvent *event);
private :
unsigned m_ref_count;
TRANSPORT_HANDLE m_transport;
_STL::list<Command *> m_commands;
_STL::string m_username;
_STL::string m_password;
};
// ========================================================
CPop3Session::CPop3Session() :
m_ref_count(0),
m_commands(),
m_username(),
m_password() {
}
CPop3Session::~CPop3Session() {
for (_STL::list<Command *>::iterator it = m_commands.begin(); it != m_commands.end(); ++it)
delete *it;
}
unsigned long DLL_CALLCONV
CPop3Session::AddRef() {
return ++m_ref_count;
}
unsigned long DLL_CALLCONV
CPop3Session::Release() {
if (--m_ref_count == 0) {
delete this;
return 0;
}
return m_ref_count;
}
HRESULT DLL_CALLCONV
CPop3Session::QueryInterface(REFIID guid, void **iif) {
if (IsEqualGUID(guid, CLSID_POP3_SESSION)) {
*iif = this;
return S_OK;
}
return E_NOINTERFACE;
}
void DLL_CALLCONV
CPop3Session::Initialize(TRANSPORT_HANDLE transport, Connection *connection) {
m_transport = transport;
}
int DLL_CALLCONV
CPop3Session::GetProtocolCount() {
return 2;
}
void DLL_CALLCONV
CPop3Session::GetProtocols(GUID *guid) {
guid[0] = CLSID_SYSTEM_PROTOCOL;
guid[1] = CLSID_POP3_PROTOCOL;
}
bool DLL_CALLCONV
CPop3Session::Receive(EpEvent *event) {
if (IsEqualGUID(event->protocol, CLSID_SYSTEM_PROTOCOL)) {
switch(event->msg) {
case SYSTEM_CONNECTION_CHANGED :
EpResetProtocol(m_transport, CLSID_POP3_PROTOCOL);
break;
};
} else {
if (!m_commands.empty())
if (m_commands.front()->type == ECT_LOGIN)
return ReceiveLogin((CommandLogin *)m_commands.front(), event);
return true;
}
return false;
}
bool DLL_CALLCONV
CPop3Session::ReceiveLogin(CommandLogin *command, EpEvent *event) {
switch(event->msg) {
case POP3_REPLY_OK :
switch(command->count++) {
case 0 :
{
EpAction action;
action.protocol = CLSID_POP3_PROTOCOL;
action.msg = POP3_PASS;
action.data = (unsigned char *)m_password.c_str();
action.size = m_password.length() + 1;
action.timeout = 1000;
EpSendAction(m_transport, &action);
break;
}
case 1 :
{
// get ready for next event
m_commands.pop_front();
delete command;
// tell the user that we logged in
EpEvent new_event;
new_event.protocol = CLSID_POP3_SESSION;
new_event.msg = POP3_LOGGED_IN;
new_event.data = NULL;
new_event.size = 0;
new_event.reference_id = 0;
EpDispatchEvent(m_transport, &new_event);
break;
}
}
break;
case POP3_REPLY_ERROR :
m_commands.pop_front();
delete command;
break;
};
return true;
}
// --------------------------------------------------------
// These functions monitors all events being passed from
// the pop3 protocol to the user and vice versa.
// --------------------------------------------------------
void DLL_CALLCONV
CPop3Session::Login(const char *username, const char *password) {
CommandLogin *command = new CommandLogin;
command->type = ECT_LOGIN;
command->count = 0;
m_commands.push_back(command);
m_username = username;
m_password = password;
EpAction action;
action.protocol = CLSID_POP3_PROTOCOL;
action.msg = POP3_USER;
action.data = (unsigned char *)m_username.c_str();
action.size = m_username.length() + 1;
action.timeout = 0;
EpSendAction(m_transport, &action);
}
/*
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 :
{
_STL::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 :
{
_STL::string message_count;
_STL::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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -