首页
社区
课程
招聘
[分享]利用邮箱实现bug提交和自动检查更新
发表于: 2013-2-27 14:19 8954

[分享]利用邮箱实现bug提交和自动检查更新

2013-2-27 14:19
8954
看了下邮件的发送与接收,了解了这方面知识,写一个帖子。

1、设置捕获
int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE h0, LPTSTR lpCmdLine, int nCmdShow)
 {
     BOOL bRet;
     MSG msg;
     HWND hwndFrame;
     
  [B][COLOR="Red"]   g_previousFilter = SetUnhandledExceptionFilter(TopLevelExceptionFilter);[/COLOR][/B]
     //_CrtSetBreakAlloc(58);
     InitCommonControls();
     g_hInst = hInst;
     //hModUxTheme = LoadLibrary(L"uxtheme.dll");
     //注册框架窗口类
   //创建框架窗口   
   //消息泵

     //if (hModUxTheme)
     //FreeLibrary(hModUxTheme);
     _CrtDumpMemoryLeaks();
     return (int) bRet;
 } 


2、捕获处理
LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *pExceptionInfo)
 {
     SYSTEMTIME time;
     LONG lRet = EXCEPTION_CONTINUE_SEARCH;
     //HRESULT hr ;
     int end;
     GetLocalTime(&time);
     char acBuf[MAX_PATH] = {0};
     // Build a string showing the date and time.
     //Returns the number of characters written to the buffer, excluding any terminating NULL characters. A negative value is returned if an error occurs.
     end = wnsprintfA(acBuf, MAX_PATH, "%d%02d%02d%02d%02d%02d.dmp",time.wYear,
         time.wMonth, time.wDay,time.wHour, time.wMinute,time.wSecond);
     
     if(end > 0)
     {
         HANDLE hFile;
         char szBugFile[MAX_PATH+1] = {0};
         GetModuleFileNameA(NULL,szBugFile,MAX_PATH + 1);
         PathRemoveFileSpecA(szBugFile);
         PathAppendA(szBugFile,acBuf);
         hFile = CreateFileA(szBugFile,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL); 

         if(hFile == INVALID_HANDLE_VALUE) 
         { 
             ;
             //WriteLog(_T("ExceptionInfo"),_T("CreateFile"),_T("-1"));
         }else{
             BOOL (__stdcall *fnMiniDumpWriteDump)(HANDLE,DWORD,HANDLE,MINIDUMP_TYPE,
                 PMINIDUMP_EXCEPTION_INFORMATION, PMINIDUMP_USER_STREAM_INFORMATION,PMINIDUMP_CALLBACK_INFORMATION); 
             //typedef BOOL (__stdcall *MiniDumpWriteDumpProc)(HANDLE,DWORD,HANDLE,MINIDUMP_TYPE,
             //PMINIDUMP_EXCEPTION_INFORMATION, PMINIDUMP_USER_STREAM_INFORMATION,PMINIDUMP_CALLBACK_INFORMATION);
             HINSTANCE hinstLib; 
             //BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; 
             //MiniDumpWriteDumpProc fnMiniDumpWriteDump;
             hinstLib = LoadLibrary(TEXT("DbgHelp.dll")); 

             if(hinstLib)
             {
                 (FARPROC&)fnMiniDumpWriteDump = ::GetProcAddress(hinstLib, "MiniDumpWriteDump");
                 //fnMiniDumpWriteDump = ( MiniDumpWriteDumpProc)::GetProcAddress(hinstLib, _T("MiniDumpWriteDump"));
                 if(fnMiniDumpWriteDump )
                 {
                     MINIDUMP_EXCEPTION_INFORMATION info;
                     info.ThreadId = ::GetCurrentThreadId();
                     info.ExceptionPointers = pExceptionInfo;
                     info.ClientPointers = FALSE;
                     BOOL bOk = fnMiniDumpWriteDump(::GetCurrentProcess,::GetCurrentProcessId(),hFile,MiniDumpNormal,&info,NULL,NULL);
                     if(bOk == FALSE) 
                         WriteLog(_T("ExceptionInfo"),_T("MiniDumpWriteDump"),_T("error(0x%x)"),GetLastError());
                     HWND hBug = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_BUGDLG), NULL, (DLGPROC)BugDlgProc,(LPARAM)&info);
                     SetWindowLong(hBug,GWL_USERDATA,(LONG)szBugFile);
                     ShowWindow(hBug,SW_NORMAL);
                     BOOL bRet;
                     MSG msg;
                     while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) 
                     { 
                         if (bRet == -1)
                         {
                             // Handle the error and possibly exit
                             break;
                         }
                         else if (!IsWindow(hBug) || !IsDialogMessage(hBug, &msg)) 
                         { 
                             TranslateMessage(&msg); 
                             DispatchMessage(&msg); 
                         } 
                     }
                     lRet = EXCEPTION_EXECUTE_HANDLER;
                 }else
                     WriteLog(_T("ExceptionInfo"),_T("MiniDumpWriteDump"),_T("Failed to get"));
                 FreeLibrary(hinstLib); 
             }else
                 WriteLog(_T("ExceptionInfo"),_T("DbgHelp.dll"),_T("Failed to load"));
         }
         CloseHandle(hFile);
         
         //SAFE_DELETE(g_pszBugFile);
     }
     //if(g_previousFilter)
     //    return g_previousFilter(pExceptionInfo);
     //else
         return lRet;
 }

3、捕获后用户窗口界面消息处理
INT_PTR CALLBACK BugDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
     switch(uMsg)
     {
     case CTLCOLOR_STATIC:
         {
             if(IDC_LINK == GetDlgCtrlID((HWND)lParam))
             {
                 HBRUSH br = CreateSolidBrush( RGB(255,255,255) );
                 return (INT_PTR)br;
             }
         }
         break;
     case WM_COMMAND:
         switch(LOWORD(wParam))
         {

         case IDC_BTNATTACH:
                 OnBugAddFiles(hWnd);
                 return 0;        
         case IDOK:
             {
                 if(BST_CHECKED == IsDlgButtonChecked(hWnd,IDC_SUBMIT))
                 {
                     BugSendMail(hWnd);
                 }
                 if(BST_CHECKED == IsDlgButtonChecked(hWnd,IDC_REBOOT))
                 {
                     TCHAR pszAppPath[MAX_PATH + 1];
                     GetModuleFileName(NULL,pszAppPath,MAX_PATH + 1);
                     ShellExecute(NULL, NULL,pszAppPath, NULL, NULL, SW_SHOWNORMAL);
                 }
             }
             break;
         case IDCANCEL:
                 DestroyWindow(hWnd);

         }
         break;
     case WM_INITDIALOG:
         {
             CenterWindow(hWnd,NULL);
             MINIDUMP_EXCEPTION_INFORMATION *pInfo = (MINIDUMP_EXCEPTION_INFORMATION*)lParam;
  

         }
         return TRUE;
     case WM_DESTROY:
         //SAFE_DELETE(g_pszAppPath);
         PostQuitMessage(0); 
         break;
     }
     return FALSE;
 } 

 //这里直接2个附件,多个附件需要改下Smtp类

void BugSendMail(HWND hWnd)
 {
     char acBugFile[MAX_PATH + 1] = {0};
     GetDlgItemTextA(hWnd,IDC_ATTACHFILE,acBugFile,MAX_PATH + 1);
     char* pMoreFile = (char*)GetWindowLong(hWnd,GWL_USERDATA);

     SetCursor( LoadCursor(NULL, IDC_WAIT) );
     Smtp smtp;
     char acount[] = "";
     DWORD dwSize;
     char  sName[MAX_COMPUTERNAME_LENGTH + 1];
     dwSize = MAX_COMPUTERNAME_LENGTH + 1;
     GetComputerNameA(sName, &dwSize);

     if(smtp.Connect("smtp.163.com") && smtp.Login(acount,"...")\
         && smtp.Send(acount,"...@qq.com",sName,"f","...",pData,acBugFile,pMoreFile,0))
         ;
     else MessageBox(NULL,_T("send failed."),_T("bug"),MB_OK|MB_ICONERROR);
     SetCursor( LoadCursor(NULL, IDC_ARROW) );

 }

 void CenterWindow(HWND hWnd,HWND hParent)
 {
     if(hParent == NULL)
         hParent = GetDesktopWindow(); 
     RECT rcParent,rc;
     GetWindowRect(hParent, &rcParent); 
     GetWindowRect(hWnd, &rc); 
     int w = rc.right-rc.left,
         h = rc.bottom-rc.top,
         x = rcParent.right - rcParent.left -w,
         y=rcParent.bottom - rcParent.top -h;
     x = rcParent.left + (long)(x/2.0 + 0.5);
     y = rcParent.top + (long)(y/2.0+0.5);
     SetWindowPos(hWnd, HWND_TOP, x, y, 0, 0,SWP_NOSIZE); 
 } 



5、检查更新
DWORD WINAPI UpdataThreadFunc( LPVOID lpParam )
{
	Pop3 pop;
	g_style |= UPDATA;
	if(pop.Connect("pop.163.com") && pop.Login("xxx@163.com","xxx"))
	{
		int nSize,k = 0,nBufSize = 0;
		int iCount = pop.Stat();
		char *pSubject,*pSubjectEnd,*pUpdataVersion,*szBuf=0;
		const char acUpdataFile[] = "Updataxx";
		const char acVer[] = "Ver=";
		const char acAddr[] = "Addr=";
		const char acSub[] = "\r\nSUBJECT: ";
		for(;iCount > 0 && (g_style & UPDATA);iCount--)
		{
			pSubject=pSubjectEnd=pUpdataVersion = 0;
			nSize = pop.List(iCount);
			if(nSize <= 0) 
				continue;
			if(nBufSize < nSize)
			{
				SAFE_DELETE_ARRAY(szBuf);
				nBufSize = nSize+1;
				szBuf = new char[nBufSize];
			}
			nSize = pop.Retr(iCount,szBuf,nSize);
			if(0 >= nSize)
				continue;
			szBuf[nSize] = 0;
                                                   //里面要放更新的内容,需要自己发邮件到此邮箱,简单的信息写在标题里就可以了然后解析,如xxx|ver=2.00|addr=xxx|xxx

		}

end:
		pop.Disconnect();
		SAFE_DELETE_ARRAY(szBuf);
	}
	g_style &= ~UPDATA;
	OutputDebugString(_T("UpdataThreadFunc return\n"));
	return 0;
}


6、邮件类
#include "Base64.h"
#include <string> 
using namespace std; 

#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
extern WORD g_style;
SOCKET InitSocket(WORD wVersionRequired = MAKEWORD(2,2));    // 创建
void ReleaseSocket(SOCKET  hSOCKET);    // 释放Socket


#define BOUNDARY "fang"                // 边界字符串
#define for if(0); else for                        // 变量作用域

//缓冲区大小,这个值必须是57的整数倍!
#define BUFFER_READ 11400

class Smtp  
{
public:
     Smtp();
     virtual ~Smtp();
private:
     SOCKET m_SOCKET;
     LPHOSTENT m_HOSTENT;
     SOCKADDR_IN m_SOCKADDR_IN;
private:
     /*
     功能:
         验证从服务器返回的前三位代码和传递进来的参数是否一样

    备注:
         211 帮助返回系统状态
        214 帮助信息
        220 服务准备就绪
        221 关闭连接
        235 用户验证成功
        250 请求操作就绪
        251 用户不在本地,转寄到其他路径
        334 等待用户输入验证信息
        354 开始邮件输入
        421 服务不可用
        450 操作未执行,邮箱忙
        451 操作中止,本地错误
        452 操作未执行,存储空间不足
        500 命令不可识别或语言错误
        501 参数语法错误
        502 命令不支技
        503 命令顺序错误
        504 命令参数不支持
        550 操作未执行,邮箱不可用
        551 非本地用户
        552 中止存储空间不足
        553 操作未执行,邮箱名不正确
        554 传输失败
    */
     BOOL CheckResponse(const char* RecvCode);
     BOOL SendFile(const char *szFile);
public:

     //接smtp服务器
    BOOL Connect(const char* SmtpAddr);//,const int Port

     //验证用户名和密码
    BOOL Login(const char* Username,const char* Password);

     //发送数据
    BOOL Send(const char* SendFrom,            // 发送地址
                  const char* SendToList,    // 目地地址列表
                  const char* SenderName,            // 发送者姓名
                  const char* ReceiverName,        // 接收者姓名
                  const char* Subject,                // 邮件主题
                  const char* Content,                // 邮件内容
                  const char* File1,        // 附件1
                   const char* File2,        // 附件2
                   BOOL IsHtml);                        // 是否以HTML格式发送
};

#endif


 class Pop3
{
public:
     Pop3();
     virtual ~Pop3();
private:
     BOOL m_bConnected;
     SOCKET m_SOCKET;
     LPHOSTENT m_HOSTENT;
     SOCKADDR_IN m_SOCKADDR_IN;
public:
     BOOL Connect(const char*  ServerAddr,const int Port = 110);
     BOOL CheckResponse(const char* Action, char *pBuf = NULL, int cSize = 0);
     BOOL Login(const char *Username,const char *Password);
     BOOL Disconnect();
     /*(STAT)
     该命令请求服务器返回信箱大小的信息,但是不包过标记为删除的邮件
    Client:STAT
     Server:+OK 2 4065
     服务器的应答包含信箱的数量以及所有邮件的大小。stat命令仅在事务状态时可用的
    */
     int Stat(DWORD *dwTotalSize = NULL);
     BOOL Dele( UINT iIndex );
     int Retr(UINT iIndex,char *Msg, int cMsg);
     /*  列表(LIST) 参数0全部,返回数量=STAT;其他返回大小,否则-1错误
    该命令请求服务器返回一个信箱中特定邮件的大小信息或者没有删除标记的所有邮件的大小信息
    Client: LIST 1
     Server:+OK 1 1046
     该命令有两种使用情形,带参和不带参。List后面如果指定邮件,则返回邮件大小信息,如上所示。  List指定的邮件如果被标识为删除或者不存在,则出错,如下所示:
    Client:LIST 5
     Server:-ERR no such message ,only message 1 thru 1 are present in your inbox
     如果List不带参数,如下所示:
     Client:LIST
     Server将返回多行应答。
    +OK
     1 1045
     2 2204
     .
     应答成功先是相应+OK,接着每一行含有一个邮件号和邮件的大小(字节数),最后是以句点"."作为结束  行。
    */
     int List(int iIndex = 0);
 }; 

 
#include "mail.h"
#include "..\header.h"


SOCKET InitSocket(WORD wVersionRequired)
 {
     WSADATA WSAData;
     SOCKET  hServer;
     if(WSAStartup(wVersionRequired,&WSAData) == SOCKET_ERROR)
         return SOCKET_ERROR;
     // Create a TCP/IP socket, no specific protocol.
     hServer = socket(AF_INET,SOCK_STREAM,0);
     return hServer;
 }

void ReleaseSocket(SOCKET  hSOCKET)
 {
     if(hSOCKET != SOCKET_ERROR) 
     {
         shutdown( hSOCKET,SD_BOTH);
         closesocket( hSOCKET);
     }
     WSACleanup();
 }

Smtp::Smtp()
 {
 }

Smtp::~Smtp()
 {
     ReleaseSocket(m_SOCKET);
 }

BOOL Smtp::CheckResponse(const char* RecvCode)
 {
     try
     {
         char Buf[1024]={0};
         if(recv(m_SOCKET,Buf,1024,0) == SOCKET_ERROR) 
         {
             WriteLog(_T("bugsend"),_T("CheckRecv"),_T("error:%ld"),WSAGetLastError());
             return false;
         }
         if(RecvCode[0] == Buf[0] && RecvCode[1] == Buf[1] && RecvCode[2] == Buf[2])
             return TRUE;
         WriteLogA("bugsend","CheckRecv",Buf);
         return  false;
     }
     catch(...)
     {
         return false;
     }
 }

BOOL Smtp::Connect(const char*  ServerAddr)//,const int Port
{
     LPSERVENT lpServEntry;
     int  iProtocolPort;
     if((m_SOCKET =InitSocket(MAKEWORD(2,2))) == SOCKET_ERROR)
         return false;
     // Lookup email server's IP address.
     if((m_HOSTENT = gethostbyname(ServerAddr))==NULL)
     {
         return false;
     }

     if(m_HOSTENT->h_addr_list[0] == NULL)
     {
         return false;
     }

     // Get the mail service port.
     lpServEntry = getservbyname( "mail" , 0);

     // Use the SMTP default port if no other port is specified.
     if (lpServEntry == NULL)
         iProtocolPort = htons(IPPORT_SMTP);
     else
         iProtocolPort = lpServEntry->s_port;

     // Setup a Socket Address structure.
     memset(&m_SOCKADDR_IN,0,sizeof(m_SOCKADDR_IN));
     m_SOCKADDR_IN.sin_family = AF_INET;
     m_SOCKADDR_IN.sin_port   = iProtocolPort;//htons(Port)
     m_SOCKADDR_IN.sin_addr.S_un.S_addr = *(ULONG *)m_HOSTENT->h_addr_list[0];

     //连接服务器
    if(connect(m_SOCKET,(sockaddr *)&m_SOCKADDR_IN,sizeof(m_SOCKADDR_IN)) == SOCKET_ERROR)
     {
         return false;
     }
     if(!CheckResponse("220")) return false;
     char szBuf[1024];
     //向服务器发送"HELO "+服务器名
    wnsprintfA(szBuf,1024,"HELO %s\r\n",ServerAddr);
     if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)    
     {
         return false;
     }
     if(!CheckResponse("250")) return false;

     return true;
 }

BOOL Smtp::Login(const char *Username,const char *Password)
 {
     Base64 base64;
     int iRet;
     //发送"AUTH LOGIN"
     if(send(m_SOCKET,"AUTH LOGIN\r\n",lstrlenA("AUTH LOGIN\r\n"),0) == SOCKET_ERROR)
     {
         return false;
     }
     if(!CheckResponse("334")) return false;
     int iLength = lstrlenA(Username);
     char *szEncode = new char[base64.GetEncodedLength(iLength) + 5];
     char *pEnd = 0;
     //发送经base64编码的用户名
    pEnd = (char*)base64.Encode((unsigned char *)Username,iLength,(unsigned char*)szEncode,0);
     lstrcpyA(pEnd,"\r\n");
     iRet = send(m_SOCKET,szEncode,lstrlenA(szEncode),0);
     SAFE_DELETE_ARRAY(szEncode);
     if(iRet == SOCKET_ERROR)
         return false;

     if(!CheckResponse("334")) return false;

     //发送经base64编码的密码
    iLength = lstrlenA(Password);
     szEncode = new char[base64.GetEncodedLength(iLength) + 5];
     pEnd = (char*)base64.Encode((unsigned char *)Password,iLength,(unsigned char*)szEncode,0);
     lstrcpyA(pEnd,"\r\n");
     iRet = send(m_SOCKET,szEncode,lstrlenA(szEncode),0);
     SAFE_DELETE_ARRAY(szEncode);
     if(iRet == SOCKET_ERROR)
         return false;
     if(!CheckResponse("235")) return false;

     return true;
 }

BOOL Smtp::SendFile(const char *szFile)
 {
     if(szFile == NULL || szFile[0] == '\0') return false;
     Base64 base64;
     char szBuf[1024];
     char *pFileName = PathFindFileNameA(szFile);
     wnsprintfA(szBuf,1024,"--%s\r\n"\
         "Content-Type:application/octet-stream;Name=\"%s\"\r\n"\
         "Content-Disposition:attachment;FileName=\"%s\"\r\n"\
         "Content-Transfer-Encoding:Base64\r\n\r\n"
         ,BOUNDARY,pFileName,pFileName);

     if(SOCKET_ERROR == send(m_SOCKET,szBuf,lstrlenA(szBuf),0))
         return false;


     HANDLE fd;

     fd=CreateFileA(szFile,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
     if(fd == INVALID_HANDLE_VALUE) {
         DisplayError(_T("Create"));
         return FALSE;
     }

     BOOL bRet = FALSE;
     char encode[18000],Buf[BUFFER_READ+1];
     int ccEncode;
     DWORD ReadSize;
     ReadFile(fd,Buf,BUFFER_READ,&ReadSize,0);
     while(ReadSize==BUFFER_READ)
     {
         base64.Encode((unsigned char*)Buf,ReadSize,(unsigned char*)encode,&ccEncode);
         if(send(m_SOCKET,encode,ccEncode,0) == SOCKET_ERROR)
         {
             goto end;
         }
         //memset(Buf,0,BUFFER_READ+1);
         ReadFile(fd,Buf,BUFFER_READ,&ReadSize,0);
     }

     char *pEnd = (char*)base64.Encode((unsigned char*)Buf,ReadSize,(unsigned char*)encode,&ccEncode);
     wnsprintfA(pEnd,5,"\r\n\r\n");
     if(send(m_SOCKET,encode,ccEncode+4,0) == SOCKET_ERROR)
     {
         goto end;
     }
     bRet = TRUE;
end:
     CloseHandle(fd);
     return bRet;
 }


BOOL Smtp::Send(const char* SendFrom,                // 发送地址
                const char* SendTo,    // 目地地址
                const char* SenderName,            // 发送者姓名
                const char* ReceiverName,            // 接收者姓名
                const char* Subject,                // 邮件主题
                const char* Content,                // 邮件内容
                const char* File1,            // 附件1
                 const char* File2,            // 附件2
                 BOOL IsHtml)                        // 是否以HTML格式发送
{
     if(SendFrom == NULL || SendFrom[0] == '\0') return FALSE;

     string strTmp;

     char szBuf[1024];
     //发送MAIL FROM:<abc@xyz.com>
     wnsprintfA(szBuf,1024,"MAIL FROM:<%s>\r\n",SendFrom);
     if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
     {
         return false;
     }
     if(!CheckResponse("250")) return false;

     //发送RCPT To:<abc@xyz.com>
     wnsprintfA(szBuf,1024,"RCPT To:<%s>\r\n",SendTo);
     if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
     {
         return false;
     }
     if(!CheckResponse("250")) return false;


     //发送"DATA\r\n"
     wnsprintfA(szBuf,1024,"DATA\r\n");
     if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
     {
         return false;
     }
     if(!CheckResponse("354")) return false;

     wnsprintfA(szBuf,1024,"From:%s<%s>\r\n"\
         "Subject:%s\r\n"\
         "MIME_Version:1.0\r\n"\
         "X-Mailer:Generator\r\n"\
         "MIME_Version:1.0\r\n"\
         "Content-type:multipart/mixed;Boundary=\"%s\"\r\n\r\n"
         ,SenderName,SendFrom,Subject,BOUNDARY );

     //先将HEADER部分发送过去
    if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
     {
         return false;    
     }

     //邮件主体
    wnsprintfA(szBuf,1024,"--%s\r\n"\
         "Content-type:text/%s;Charset=gb2312\r\n"\
         "Content-Transfer-Encoding:8bit\r\n\r\n"
         ,BOUNDARY,IsHtml ? "html" : "plain");
     if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
     {
         return false;    
     }
     //将邮件内容发送出去
    if(send(m_SOCKET,Content,lstrlenA(Content),0) == SOCKET_ERROR)
     {
         return false;    
     }
     wnsprintfA(szBuf,1024,"\r\n\r\n");
     if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
     {
         return false;    
     }
     /*
     附件处理
    对文件内容分段进行base64编码,编码一小段,传送一小段
    */
     SendFile(File1);
     SendFile(File2);

     //界尾
    wnsprintfA(szBuf,1024,"--"BOUNDARY"--\r\n.\r\n");
     if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
     {
         return false;    
     }
     if(!CheckResponse("250")) return false;

     //退出
    wnsprintfA(szBuf,1024,"QUIT\r\n");
     if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
     {
         return false;
     }
     if(!CheckResponse("221")) return false;
     return true;
 }

Pop3::Pop3()
 {
     m_bConnected = FALSE;
 }

Pop3::~Pop3()
 {
     if( m_bConnected )
         Disconnect();
     ReleaseSocket(m_SOCKET);
 }

BOOL Pop3::CheckResponse(const char* Action,char* pBuf,int cSize)
 {
     try
     {
         char szBuf[1024];
         int iLength;
         if(pBuf == NULL)
         {
             pBuf = szBuf;
             cSize = 1024;
         }
         iLength = recv(m_SOCKET,pBuf,cSize,0);
         if(iLength == SOCKET_ERROR) 
         {
             WriteLog(_T("updata"),_T("CheckRecv"),_T("error:%ld"),WSAGetLastError());
             return FALSE;
         }

         if (0 == StrCmpNIA(pBuf,"-ERR",4))
         {
             WriteLogA("updata",Action,pBuf);
             return FALSE;     
         }
         return iLength;
     }
     catch(...)
     {
         return false;
     }
 }

BOOL Pop3::Connect(const char*  ServerAddr,const int Port)
 {
     SOCKADDR_IN    SockAddr;
     //SOCKET         hServer;
     //LPSERVENT lpServEntry;
     if((m_SOCKET = InitSocket(MAKEWORD(2,2))) == SOCKET_ERROR)
         return false;
     // Lookup email server's IP address.
     if((m_HOSTENT = gethostbyname(ServerAddr))==NULL)
     {
         return false;
     }

     if(m_HOSTENT->h_addr_list[0] == NULL)
     {
         return false;
     }

     // Setup a Socket Address structure.
     SockAddr.sin_family = AF_INET;
     SockAddr.sin_port = htons(Port);
     SockAddr.sin_addr = *((LPIN_ADDR)*m_HOSTENT->h_addr_list);
     //int nNetTimeout = 30000; //30秒
    //setsockopt(m_SOCKET,SOL_SOCKET,SO_RCVTIMEO,(char* )&nNetTimeout,sizeof(int));
     // Connect the Socket.
     if (connect( m_SOCKET, (PSOCKADDR) &SockAddr, sizeof(SockAddr)) == SOCKET_ERROR)
         return FALSE;
     if(!CheckResponse("connect server")) return false;
     return TRUE;
 }

BOOL Pop3::Login(const char *Username,const char *Password)
 {
     char szBuf[1024];
     wnsprintfA(szBuf,1024,"USER %s\r\n",Username);
     if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
         return false;
     if(!CheckResponse("USER")) return FALSE;
         wnsprintfA(szBuf,1024,"PASS %s\r\n",Password);
     if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
         return false;
     if(!CheckResponse("PASS")) return FALSE;
     m_bConnected = TRUE;
     return TRUE;
 }

BOOL Pop3::Disconnect()
 {
     //BOOL ret;
     if( !m_bConnected )
         return TRUE;
     // Disconnect gracefully from the server and close the socket
     char szBuf[20];
     lstrcpynA(szBuf,"QUIT\r\n",20);
     send(m_SOCKET,szBuf,lstrlenA(szBuf),0);
     // No need to check return value here.If it fails, the message is available with GetLastError
     m_bConnected = FALSE;
     return CheckResponse("QUIT");
 }

int Pop3::Stat(DWORD *dwTotalSize)
 {
     char szBuf[1024];
     lstrcpynA(szBuf,"STAT\r\n",20);
     send(m_SOCKET,szBuf,lstrlenA(szBuf),0);

     if( !CheckResponse("STAT",szBuf,1024) ) return -1;

     char* pNum =StrPBrkA(szBuf,"0123456789");
     if (pNum == NULL) return -1;
     int sum = strtol(pNum,&pNum,10);
     if(dwTotalSize)
         *dwTotalSize = strtoul(pNum + 1,&pNum,10);
     return sum;

 }

BOOL Pop3::Dele( UINT iIndex )
 {
     char szBuf[1024];
     wnsprintfA(szBuf,20,"DELE %d\r\n",iIndex);
     send(m_SOCKET,szBuf,lstrlenA(szBuf),0);
     return CheckResponse("DELE");
 }

int Pop3::List(int iIndex)
 {
     if(iIndex == 0)
         return Stat();
     char szBuf[1024];
     wnsprintfA(szBuf,20,"LIST %d\r\n",iIndex);
     send(m_SOCKET,szBuf,lstrlenA(szBuf),0);
     if(0 >= CheckResponse("LIST",szBuf,1024) ) return -1;
     int i = 0,size = 0;
     sscanf_s(szBuf,"%*s%d%d",&i, &size);
     return size;
 }

int Pop3::Retr( UINT iIndex,char *Msg, int cMsg)
 {
     if(iIndex <= 0 || Msg == 0 || !(g_style & UPDATA))
         return -1;
     char szBuf[1024];
     int nChars,nHasRev = 0,nDesire = cMsg;
     Msg[0] = '\0';
     wnsprintfA(szBuf,1024,"RETR %d\r\n",iIndex);
     send(m_SOCKET,szBuf,lstrlenA(szBuf),0);
     //Sleep(1000);
     nChars = CheckResponse("RETR",Msg,cMsg);
     while(nDesire > 0 && (g_style & UPDATA))
     {    
         if(nChars < 0){
             // 由于是非阻塞的模式,所以当errno为EAGAIN时,表示当前缓冲区已无数据可读
            // 在这里就当作是该次事件已处理处.
             if(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
                 nDesire = 1;
             else
                 break;
         }
         //else if(nChars == 0)
         //    break;//这里表示对端的socket已正常关闭
        //else if(nChars == nDesire)
         //    nDesire = 1;
         if(nHasRev >= cMsg)//把缓冲区的内容拷完耗尽,免得下次拷到这里的内容
        {
             nChars = recv(m_SOCKET,szBuf,1024,0);
             nDesire = 1024;
         }
         else
         {
             nHasRev += nChars;
             nDesire = cMsg-nHasRev;
             nChars = recv(m_SOCKET,Msg+nHasRev,nDesire,0);        
         }
     }
     return nHasRev;
 }


 #ifndef _BASE64
#define _BASE64

class Base64
{

public:

     /*编码
    DataByte
         [in]输入的数据长度,以字节为单位
    */
     unsigned char* Encode(const unsigned char* Data,int DataByte, unsigned char* strEncode,int *outLength);
     int GetEncodedLength(int iLength);
     /*解码
    DataByte
         [in]输入的数据长度,以字节为单位
    OutByte
         [out]输出的数据长度,以字节为单位,请不要通过返回值计算
        输出数据的长度
    */
     unsigned char* Decode(const char* Data,int DataByte,int& OutByte,unsigned char *strDecode);
 };
#endif #include "Base64.h"

int Base64::GetEncodedLength(const int iLength)
 {
     return ((iLength/3 +1) << 2)+1;
 }

unsigned char* Base64::Encode(const unsigned char* Data,int DataByte,unsigned char* strEncode,int *outLength)
 {
     //编码表
    const char EncodeTable[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     unsigned char Tmp[3]={0};
     int LineLength=0,DataByte3 = (int)(DataByte / 3);
     int iLength = 0;
     for(int i=0; i < DataByte3; i++)
     {
         Tmp[0] = *Data++;
         Tmp[1] = *Data++;
         Tmp[2] = *Data++;

         *strEncode++= EncodeTable[Tmp[0] >> 2];
         *strEncode++= EncodeTable[((Tmp[0] << 4) | (Tmp[1] >> 4)) & 0x3F];
         *strEncode++= EncodeTable[((Tmp[1] << 2) | (Tmp[2] >> 6)) & 0x3F];
         *strEncode++= EncodeTable[Tmp[2] & 0x3F];
         iLength += 4;
         if(LineLength+=4,LineLength==76) 
         {
             *strEncode++='\r';
             *strEncode++='\n';
             iLength += 2;
             LineLength=0;
         }
     }

     //对剩余数据进行编码
    int Mod=DataByte % 3;
     if(Mod==1)
     {
         Tmp[0] = *Data++;
         *strEncode++ = EncodeTable[(Tmp[0] & 0xFC) >> 2];
         *strEncode++ = EncodeTable[((Tmp[0] & 0x03) << 4)];
         *strEncode++ = '=';
         *strEncode++ = '=';
         iLength += 4;
     }
     else if(Mod==2)
     {
         Tmp[0] = *Data++;
         Tmp[1] = *Data++;
         *strEncode++ = EncodeTable[(Tmp[0] & 0xFC) >> 2];
         *strEncode++ = EncodeTable[((Tmp[0] & 0x03) << 4) | ((Tmp[1] & 0xF0) >> 4)];
         *strEncode++ = EncodeTable[((Tmp[1] & 0x0F) << 2)];
         *strEncode++ = '=';
         iLength += 4;
     }
     if(outLength) *outLength = iLength;
     return strEncode;
 }

unsigned char* Base64::Decode(const char* Data,int DataByte,int& OutByte, unsigned char* strDecode)
 {
     //解码表
    const char DecodeTable[] =
     {
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         62, // '+'
         0, 0, 0,
         63, // '/'
         52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
         0, 0, 0, 0, 0, 0, 0,
         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
         13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z'
         0, 0, 0, 0, 0, 0,
         26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
         39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z'
     };

     int nValue;
     int i= 0;
  
     while (i < DataByte)
     {
         if (*Data != '\r' && *Data!='\n')
         {
             nValue = DecodeTable[*Data++] << 18;
             nValue += DecodeTable[*Data++] << 12;
             *strDecode++=(nValue & 0x00FF0000) >> 16;
             OutByte++;
  
             if (*Data != '=')
             {
                 nValue += DecodeTable[*Data++] << 6;
                 *strDecode++=(nValue & 0x0000FF00) >> 8;
                 OutByte++;
  
                 if (*Data != '=')
                 {
                     nValue += DecodeTable[*Data++];
                     *strDecode++=nValue & 0x000000FF;
                     OutByte++;
                 }
             }
             i += 4;
         }
         else// 回车换行,跳过
        {
             Data++;
             i++;
         }
      }
     return strDecode;
 }


[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 6
支持
分享
最新回复 (14)
雪    币: 566
活跃值: (4409)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
good idea
2013-2-27 16:34
0
雪    币: 66
活跃值: (183)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
nice 啊,指令邮件
2013-2-27 22:00
0
雪    币: 967
活跃值: (1138)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
不行!谁有这么笨啊 邮箱账户密码 不明摆着!这样会导致大面积种马的
2013-2-27 22:11
0
雪    币: 656
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
5
好东西,收藏!!
2013-2-28 21:11
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
坐等楼主解释这个问题!
2013-2-28 21:29
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
想法是不错滴,lz创新精神不错
2013-2-28 21:30
0
雪    币: 2733
活跃值: (2550)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
太复杂了,直接读取空间、博客、微博什么的内容不就完了。
2013-2-28 21:37
0
雪    币: 170
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
mark一下,回头学习~
2013-3-1 09:38
0
雪    币: 21
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
这个  收下呵呵 不错
2013-3-1 21:50
0
雪    币: 199
活跃值: (65)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
11
MARK一下,感谢楼主的无私分享!
2013-3-2 14:47
0
雪    币: 471
活跃值: (3703)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
12
mark!!!1
2013-3-3 18:47
0
雪    币: 93908
活跃值: (200199)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
13
Thanks for share.
2013-3-3 19:20
0
雪    币: 107
活跃值: (326)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
有点意思............
2013-3-4 00:45
0
雪    币: 27
活跃值: (36)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
收藏!!!!
2013-3-3 21:05
0
游客
登录 | 注册 方可回帖
返回
//