root/SendMail.cpp
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- 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;
}