root/SendMail.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. SendMail

/*
 * Copyright (C) 2002-2003 chik & s.hiranaka
 * For license terms, see the file COPYING in this directory.
 */

#include "stdafx.h"
#include "Pochy.h"
#include "MainFrm.h"
#include "DraftFrame.h"
#include "Sock.h"
#include "CodeConvert.h"
#include "sendmail.h"
#include "direct.h"
#include "PassPhraseDlg.h"
#include "lib.h"
#include "DraftSendDlg.h"

#define send_command(mes) \
                send(SmtpSocket.m_sock, command, command.GetLength(), 0);\
                if(SmtpSocket.SockRead(buf) == -1)\
                        throw mes;\
                if(buf.Find("250") != 0 && buf.Find("354") != 0 && buf.Find("221") != 0)\
                        throw buf.GetBuffer(0);\
                g_log("log-sendmail", command);\
                g_log("log-sendmail", buf);\
                df->m_send_dlg->m_status.SetWindowText(buf);\
                buf.Empty()

UINT SendMail(LPVOID pParam)
{
        CSock SmtpSocket;
        CSock PopSocket;
        CString smtp_ip;
        CString smtp_addr;
        CString smtp_port;
        CString buf;
        CString command;
        int left;
        int right;
        BOOL pop_before_smtp;

        CDraftFrame *df = (CDraftFrame *)pParam;
        CPochyApp* app = (CPochyApp*)AfxGetApp();
        CMainFrame *mf = (CMainFrame *)app->m_pMainWnd;

        CListCtrl &lc = df->m_pListV2->GetListCtrl();

        // iniファイルのための準備
        CString path = app->m_app_path + "\\" + df->m_account + "\\account.ini";

        // headerの確認
        if(df->m_me.GetTo().IsEmpty()){
                df->MessageBox("To: フィールドが空です", df->m_account+" - header error");
                df->m_send_dlg->EndDialog(0);
                df->m_send_dlg = NULL;
                df->EnableWindow(TRUE);
                return FALSE;
        }
        if(df->m_me.GetFrom().IsEmpty()){
                df->MessageBox("From: フィールドが空です", df->m_account+" - header error");
                df->m_send_dlg->EndDialog(0);
                df->m_send_dlg = NULL;
                df->EnableWindow(TRUE);
                return FALSE;
        }

        // pop before smtpかどうか
        pop_before_smtp = GetPrivateProfileInt("pop", "pop_before_smtp", 0, path);
        if(pop_before_smtp){
                try{
                        CString message;
                        CString pop_addr;
                        GetPrivateProfileString("pop", "server_addr", "", pop_addr.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
                        CString pop_port;
                        GetPrivateProfileString("pop", "port", "", pop_port.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);

                        if(INVALID_SOCKET == PopSocket.Connect6(pop_addr.GetBuffer(0), pop_port.GetBuffer(0))){
                                throw "cannot establish connection";
                        }
                        PopSocket.SockRead(buf);
                        df->m_send_dlg->m_status.SetWindowText(buf);
                        buf.Empty();

                        // user
                        CString pop_user;
                        GetPrivateProfileString("pop", "user", "", pop_user.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
                        pop_user.ReleaseBuffer();
                        pop_user = "user " + g_cstr_chop2(pop_user) + "\r\n";
                        send(PopSocket.m_sock, pop_user.GetBuffer(10), pop_user.GetLength(), 0);
                        if(PopSocket.SockRead(buf) == -1){
                                throw "error is occured in user session";
                        }
                        df->m_send_dlg->m_status.SetWindowText(buf);
                        buf.Empty();

                        // pass
                        CString pop_pass;
                        GetPrivateProfileString("pop", "pass", "", pop_pass.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
                        pop_pass.ReleaseBuffer();
                        if(!pop_pass.IsEmpty())
                                pop_pass = "pass " + g_cstr_chop2(pop_pass) + "\r\n";
                        else if(pop_pass.IsEmpty() && !app->m_pop_passphrase.IsEmpty())
                                pop_pass = "pass " + app->m_pop_passphrase + "\r\n";
                        else if(pop_pass.IsEmpty() && app->m_pop_passphrase.IsEmpty()){
                                CPassPhraseDlg passDlg;
                                passDlg.SetFlag(POP);
                                passDlg.DoModal();
                                pop_pass = "pass " + app->m_pop_passphrase + "\r\n";
                        }
                        send(PopSocket.m_sock, pop_pass.GetBuffer(10), pop_pass.GetLength(), 0);
                        if(PopSocket.SockRead(buf) == -1){
                                throw "error is occured in pass session";
                        }
                        if(buf.Find("-ERR") == 0 || buf.Find("-err") == 0){
                                message.Format("%s", buf.GetBuffer(0));
                                throw message.GetBuffer(0);
                        }
                        buf = "pass ********";
                        df->m_send_dlg->m_status.SetWindowText(buf);
                        buf.Empty();

                        // quit
                        send(PopSocket.m_sock, "quit\r\n", strlen("quit\r\n"), 0);
                        PopSocket.SockRead(buf);
                        buf.Empty();
                        PopSocket.DisConnect();
                }
                catch(char *errorstr){
                        send(PopSocket.m_sock, "quit\r\n", strlen("quit\r\n"), 0);
                        // socketを閉じる
                        PopSocket.DisConnect();
                        df->MessageBox(errorstr, df->m_account+" - pop before smtp error");
                        df->m_send_dlg->EndDialog(0);
                        df->m_send_dlg = NULL;
                        df->EnableWindow(TRUE);
                        return FALSE;
                }
                // pop before smtp が機能するまでに時間がかかるので、念のため
                Sleep(10000);
        }

        try{
                // smtp接続準備
                GetPrivateProfileString("smtp", "server_addr", "", smtp_addr.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
                GetPrivateProfileString("smtp", "port", "", smtp_port.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);

                if(INVALID_SOCKET == SmtpSocket.Connect6(smtp_addr.GetBuffer(0), smtp_port.GetBuffer(0))){
                        throw "cannot establish connection";
                }
//============== セッション開始 ============
                CString date;
                CTime t = CTime::GetCurrentTime();
                date.Format("%02d/%02d/%d %02d:%02d:%02d",t.GetDay(),t.GetMonth(),t.GetYear(),t.GetHour(),t.GetMinute(),t.GetSecond());
                g_log("log-sendmail", "------- "+ date +" -------\r\n");
                if(SmtpSocket.SockRead(buf) == -1)
                        throw "in connection";
                g_log("log-sendmail", buf);
                df->m_send_dlg->m_status.SetWindowText(buf);
                buf.Empty();
        //-------------- helo ------------------
                char tmpbuf[256];
                gethostname(tmpbuf, 255);
                CString hostname = tmpbuf;
                if(hostname.IsEmpty())
                        hostname = "unknown";
                command="helo "+hostname+"\r\n";
                send_command("at HELO command");
        //-------------- mail from -------------
                command = "mail from: "+g_cstr_chop2(g_ma(df->m_me.GetFrom()))+"\r\n";
                send_command("at MAIL FROM command");
        //-------------- rcpt ------------------
                left = 0;
                CString to = df->m_me.GetTo();
                if(!df->m_me.GetCc().IsEmpty())
                        to += ", "+df->m_me.GetCc();
                if(!df->m_me.GetBcc().IsEmpty())
                        to += ", "+df->m_me.GetBcc();
                g_strip_part(to, "\""); // ""の部分を削除(コメント中に、,があるとやばいので)
                right = to.Find(",");
                while(right != -1){
                        command = "rcpt to: "+g_cstr_chop2(g_ma(to.Mid(left, right-left)))+"\r\n";
                        send_command("at RCPT TO command");
                        left = right+1;
                        right = to.Find(",", left);
                }
                command = "rcpt to: "+g_cstr_chop2(g_ma(to.Mid(left,to.GetLength()-left)))+"\r\n";
                send_command("at RCPT TO command");

                //-------------- body ------------------
                CString path = app->m_app_path + "\\" + df->m_account + "\\outbox";

                // bodyの送信
                command = "data\r\n";
                send_command("at BODY command");
                CString mail = df->m_me.GetMail(ME_GET_SEND);
                mail.Replace("\r\n.", "\r\n..");

                int whole_len = mail.GetLength();
                int current_len;
                int part_len;
                part_len = current_len = mail.GetLength()/8;

                df->m_send_dlg->m_progress.SetRange32(0, whole_len);
                df->m_send_dlg->m_progress.SetPos(0);
                while(current_len < whole_len){
                        buf = mail.Left(part_len);
                        mail = mail.Mid(part_len);
                        send(SmtpSocket.m_sock, buf, buf.GetLength(), 0);
                        buf.Empty();
                        df->m_send_dlg->m_progress.SetPos(current_len);
                        current_len += part_len;
                }
                send(SmtpSocket.m_sock, mail, mail.GetLength(), 0);
                df->m_send_dlg->m_progress.SetPos(whole_len);

                send(SmtpSocket.m_sock, "\r\n.\r\n", strlen("\r\n.\r\n"), 0);

                CSummaryView *sv = mf->m_pListV;
                sv->SaveMail(path, df->m_me.GetMail(ME_GET_OUTBOX), SMRY_STATUS_NONE, SMRY_COLUMN_TO);

                if(SmtpSocket.SockRead(buf) == -1)
                        throw "at BODY command";
                g_log("log-sendmail", buf);
                df->m_send_dlg->m_status.SetWindowText(buf);
                buf.Empty();

        //-------------- quit ----------------
                command = "quit\r\n";
                send_command("at QUIT command");
                // socketを閉じる
                SmtpSocket.DisConnect();
        }
        catch(char* errorstr){
                send(SmtpSocket.m_sock, "quit\r\n", 6, 0);
                // socketを閉じる
                SmtpSocket.DisConnect();
                df->MessageBox(errorstr, df->m_account+" - smtp error");
                df->EnableWindow(TRUE);
                df->m_send_dlg->m_status.SetWindowText("");
                df->m_send_dlg->EndDialog(0);
                df->m_send_dlg = NULL;
                return FALSE;
        }

        df->m_send_dlg->m_status.SetWindowText("");
        df->EnableWindow(TRUE);

        for(int i=0; i<app->m_draft_array.GetSize(); i++){
                if(df == app->m_draft_array[i])
                        app->m_draft_array.RemoveAt(i);
        }

        df->m_send_dlg->EndDialog(0);
        df->m_send_dlg = NULL;
        PostMessage(df->m_hWnd, WM_COMMAND, WM_END, NULL);
        return TRUE;
}

/* [<][>][^][v][top][bottom][index][help] */