⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pop3.cpp

📁 .net 方面的开发说明资料。
💻 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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -