root/MimeEncode.cpp
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- CMimeEncode
- CMimeEncode
- Initialize
- HowManyAttach
- HowManyPart
- CopyFrom
- GetAttach
- GetBcc
- GetCc
- GetFrom
- GetInReplyTo
- GetSubject
- GetDate
- GetMail
- GetMultipartBody
- GetMultipartEncType
- GetMultipartFileName
- GetMultipartPath
- GetMultipartType
- GetTo
- GetMessageID
- GetReplyTo
- AddAttach
- SetBcc
- SetCc
- SetFrom
- SetInReplyTo
- SetDate
- AddMultipart
- SetMultipart
- SetMultipartBody
- SetSubject
- SetTo
- SetXMailer
- SetMessageID
- SetReplyTo
- EncodeHeader
- EncodeBase64FromFile
- AddAttachedFile
- AddPgpKey
- AddPgpEncrypted
- AddText
- RemoveMultipart
- AddRFC822
- GetCT
- GetCD
- GetCTE
- GetBody
- SetMode
- GetMode
- EncodeBase64
/*
* Copyright (C) 2002-2003 chik, s.hiranaka
* For license terms, see the file COPYING in this directory.
*/
// MimeEncode.cpp: CMimeEncode クラスのインプリメンテーション
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Pochy.h"
#include "MimeEncode.h"
#include "base64.h"
#include "CodeConvert.h"
#include "lib.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// 構築/消滅
//////////////////////////////////////////////////////////////////////
CMimeEncode::CMimeEncode()
{
this->Initialize();
}
CMimeEncode::~CMimeEncode()
{
}
void CMimeEncode::Initialize()
{
m_data.m_attach.RemoveAll();
m_data.m_multipart.RemoveAll();
m_data.m_bcc.Empty();
m_data.m_cc.Empty();
m_data.m_from.Empty();
m_data.m_in_reply_to.Empty();
m_data.m_reply_to.Empty();
m_data.m_message_id.Empty();
m_data.m_subject.Empty();
m_data.m_to.Empty();
m_data.m_date.Empty();
m_data.m_xmailer.Empty();
m_mime_mode = ME_MODE_NONE;
}
int CMimeEncode::HowManyAttach()
{
return m_data.m_attach.GetSize();
}
int CMimeEncode::HowManyPart()
{
return m_data.m_multipart.GetSize();
}
void CMimeEncode::CopyFrom(CMimeEncode *me)
{
Initialize();
m_data.m_bcc = me->m_data.m_bcc;
m_data.m_cc = me->m_data.m_cc;
m_data.m_from = me->m_data.m_from;
m_data.m_in_reply_to = me->m_data.m_in_reply_to;
m_data.m_message_id = me->m_data.m_message_id;
m_data.m_reply_to = me->m_data.m_reply_to;
m_data.m_subject = me->m_data.m_subject;
m_data.m_to = me->m_data.m_to;
m_mime_mode = me->m_mime_mode;
int i=0;
while(i < me->HowManyAttach()){
m_data.m_attach.Add(me->m_data.m_attach[i]);
i++;
}
i=0;
while(i < me->HowManyPart()){
m_data.m_multipart.Add(me->m_data.m_multipart[i]);
i++;
}
}
CString CMimeEncode::GetAttach(int part)
{
return m_data.m_attach[part];
}
CString CMimeEncode::GetBcc()
{
return m_data.m_bcc;
}
CString CMimeEncode::GetCc()
{
return m_data.m_cc;
}
CString CMimeEncode::GetFrom()
{
return m_data.m_from;
}
CString CMimeEncode::GetInReplyTo()
{
return m_data.m_in_reply_to;
}
CString CMimeEncode::GetSubject()
{
return m_data.m_subject;
}
CString CMimeEncode::GetDate()
{
return m_data.m_date;
}
CString CMimeEncode::GetMail(int for_what)
{
CString header;
CString mail;
// ヘッダの構成
// RFC 822 To: Pooh Lovers:pooh@100acre.woodwest.uk,piglet@beech.tree.uk; not yet.
if(for_what != ME_GET_PRE_ENC_PGP){
header += "To: "+GetTo()+"\r\n";
header += "From: "+GetFrom()+"\r\n";
header += "Subject: "+GetSubject()+"\r\n";
if(!GetCc().IsEmpty())
header += "Cc: "+GetCc()+"\r\n";
if(!GetInReplyTo().IsEmpty())
header += "In-reply-to: "+GetInReplyTo()+"\r\n";
if(!GetReplyTo().IsEmpty())
header += "Reply-To: "+GetReplyTo()+"\r\n";
if((for_what == ME_GET_DRAFT || for_what == ME_GET_OUTBOX) && !GetBcc().IsEmpty())
header += "Bcc: "+GetBcc()+"\r\n";
if(!GetMessageID().IsEmpty())
header += "Message-ID: "+GetMessageID()+"\r\n";
if(!m_data.m_date.IsEmpty())
header += "Date: "+GetDate()+"\r\n";
if(!m_data.m_xmailer.IsEmpty())
header += "X-Mailer: "+m_data.m_xmailer+"\r\n";
header += "MIME-Version: 1.0\r\n";
}
// bodyを持たないmultipartを削除(draftに保存される場合は例外)
int i = 0;
if(for_what != ME_GET_DRAFT){
while(i < HowManyPart()){
if(m_data.m_multipart[i].m_body.IsEmpty()){
m_data.m_multipart.RemoveAt(i);
continue;
}
i++;
}
}
CString body;
if(0==HowManyPart()){
header += "Content-Type: Text/Plain; charset=ISO-2022-JP\r\n";
header += "Content-Transfer-Encoding: 7bit\r\n";
CCodeConvert cc(header);
header = cc.ToJis();
EncodeHeader(header);
mail = header + "\r\n";
}else if(1==HowManyPart()){
if(!GetCT(0).IsEmpty()) header += GetCT(0)+"\r\n";
if(!GetCTE(0).IsEmpty()) header += GetCTE(0)+"\r\n";
if(!GetCD(0).IsEmpty()) header += GetCD(0)+"\r\n";
CCodeConvert cc(header);
header = cc.ToJis();
EncodeHeader(header);
body = GetBody(0);
CCodeConvert cc2(body);
body = cc2.ToJis();
mail = header+"\r\n"+body;
}else{
if(m_mime_mode == ME_MODE_NONE){
header += "Content-Type: Multipart/Mixed; boundary=----kyoukaisen\r\n";
header += "Content-Transfer-Encoding: 7bit\r\n";
}
else if(m_mime_mode == ME_MODE_PGP){
header += "Content-Type: Multipart/Encrypted; boundary=----kyoukaisen; protocol=application/pgp-encrypted\r\n";
header += "Content-Transfer-Encoding: 7bit\r\n";
}
else if(m_mime_mode == ME_MODE_RFC822){}
CCodeConvert cc(header);
header = cc.ToJis();
EncodeHeader(header);
i = 0;
while(i < HowManyPart()){
body += "------kyoukaisen\r\n";
if(!GetCT(i).IsEmpty()) body += GetCT(i)+"\r\n";
if(!GetCTE(i).IsEmpty()) body += GetCTE(i)+"\r\n";
if(!GetCD(i).IsEmpty()) body += GetCD(i)+"\r\n";
body += "\r\n";
body += GetBody(i);
body.TrimRight();
body += "\r\n\r\n";
i++;
}
body += "------kyoukaisen--\r\n";
CCodeConvert cc2(body);
body = cc2.ToJis();
mail = header+"\r\n"+body;
}
return mail;
}
CString CMimeEncode::GetMultipartBody(int part)
{
return m_data.m_multipart[part].m_body;
}
CString CMimeEncode::GetMultipartEncType(int part)
{
return m_data.m_multipart[part].m_encoding_type;
}
CString CMimeEncode::GetMultipartFileName(int part)
{
return m_data.m_multipart[part].m_file_name;
}
CString CMimeEncode::GetMultipartPath(int part)
{
return m_data.m_multipart[part].m_path;
}
CString CMimeEncode::GetMultipartType(int part)
{
return m_data.m_multipart[part].m_type;
}
CString CMimeEncode::GetTo()
{
return m_data.m_to;
}
CString CMimeEncode::GetMessageID()
{
return m_data.m_message_id;
}
CString CMimeEncode::GetReplyTo()
{
return m_data.m_reply_to;
}
void CMimeEncode::AddAttach(CString attach)
{
m_data.m_attach.Add(attach);
}
void CMimeEncode::SetBcc(CString bcc)
{
m_data.m_bcc = bcc;
}
void CMimeEncode::SetCc(CString cc)
{
m_data.m_cc = cc;
}
void CMimeEncode::SetFrom(CString from)
{
m_data.m_from = from;
}
void CMimeEncode::SetInReplyTo(CString in_reply_to)
{
m_data.m_in_reply_to = in_reply_to;
}
void CMimeEncode::SetDate(CString date)
{
m_data.m_date = date;
}
void CMimeEncode::AddMultipart(MULTIPART_STRUCT2 &multipart)
{
m_data.m_multipart.Add(multipart);
}
void CMimeEncode::SetMultipart(int part, MULTIPART_STRUCT2 &multipart)
{
m_data.m_multipart.SetAt(part, multipart);
}
void CMimeEncode::SetMultipartBody(int part, CString body)
{
m_data.m_multipart[part].m_body = body;
}
void CMimeEncode::SetSubject(CString subject)
{
m_data.m_subject = subject;
}
void CMimeEncode::SetTo(CString to)
{
m_data.m_to = to;
}
void CMimeEncode::SetXMailer(CString xmailer)
{
m_data.m_xmailer = xmailer;
}
void CMimeEncode::SetMessageID(CString message_id)
{
m_data.m_message_id = message_id;
}
void CMimeEncode::SetReplyTo(CString reply_to)
{
m_data.m_reply_to = reply_to;
}
void CMimeEncode::EncodeHeader(CString& org)
{
int i = 0;
int j = 0;
int istart;
CString dst;
CString tmp;
CString tmp2;
CString tmp3;
unsigned char *out;
const int size = 30;
BOOL folding_space = FALSE;
CStringArray array_org;
CStringArray array_dst;
CStringArray array_tmp;
CString buf;
CString buf2;
if(org.IsEmpty())
return;
array_org.RemoveAll();
array_dst.RemoveAll();
array_tmp.RemoveAll();
g_cstr2cstra(org, array_org, "\r\n");
i = 0;
while(i < array_org.GetSize()){
buf = array_org.GetAt(i);
buf.TrimRight();
array_tmp.RemoveAll();
j = 0;
while(j < buf.GetLength()){
// search non-ascii char
if(buf[j]==0x1b && buf[j+1]==0x24 && buf[j+2]==0x42){
istart=j;
j+=3;
for(;j<buf.GetLength()-2 && (buf[j]!=0x1b || buf[j+1]!=0x28 || buf[j+2]!=0x42);j++);
j+=3;
// pick out non-ascii char
tmp=buf.Mid(istart, j-istart);
// need to confirm whether or not length of line is less than 57.
if(!buf2.IsEmpty()){
buf2.TrimRight();
buf2+="\r\n";
while(buf2.GetLength() > 76){
array_tmp.Add(buf2.Left(76)+"\r\n");
buf2 = buf2.Mid(76);
}
array_tmp.Add(buf2);
buf2.Empty();
}
while(tmp.GetLength() > 40){
tmp3 = tmp.Left(40);
tmp = tmp.Mid(40);
out = (unsigned char *)tmp2.GetBuffer(tmp3.GetLength()*3);
to64frombits(out, (unsigned char *)tmp3.GetBuffer(0), tmp3.GetLength());
tmp2.ReleaseBuffer();
tmp2 = "=?ISO-2022-JP?B?"+tmp2+"?=\r\n";
array_tmp.Add(tmp2);
tmp2.Empty();
tmp3.Empty();
}
out = (unsigned char *)tmp2.GetBuffer(tmp.GetLength()*3);
to64frombits(out, (unsigned char *)tmp.GetBuffer(0), tmp.GetLength());
tmp2.ReleaseBuffer();
tmp2 = "=?ISO-2022-JP?B?"+tmp2+"?=";
tmp2.TrimRight();
tmp2+="\r\n";
array_tmp.Add(tmp2);
tmp2.Empty();
}else{
buf2+=buf[j];
j++;
}
}
// need to confirm length of line
if(!buf2.IsEmpty() && (buf2 != "\r\n")){
buf2.TrimRight(); buf2+="\r\n";
array_tmp.Add(buf2); buf2.Empty();
}
j = 1;
while(j < array_tmp.GetSize()){
array_tmp.SetAt(j, " "+array_tmp.GetAt(j));
j++;
}
j = 0;
while(j < array_tmp.GetSize()){
array_dst.Add(array_tmp.GetAt(j));
j++;
}
i++;
}
g_cstra2cstr(array_dst, org, g_cstra_getsize(array_dst));
}
BOOL CMimeEncode::EncodeBase64FromFile(CString path, CString &buf)
{
FILE *file;
unsigned char in[READBUFSIZE*3];
unsigned char out[READBUFSIZE*4+(2*READBUFSIZE/76)+1];
CString msg;
DWORD size = g_getfs(path);
file = fopen(path, "rb");
if(file == NULL){
msg.Format("cannot open %s", path);
AfxMessageBox(msg);
return FALSE;
}
CString c;
CString tmp;
char *ptmp = tmp.GetBuffer(g_getfs(path)/5*7);
int len = 0;
while(1){
if(size > READBUFSIZE*3){
fread(in, sizeof(unsigned char), READBUFSIZE*3, file);
to64frombits(out, in, READBUFSIZE*3);
c = out;
c += "\r\n";
strcpy(ptmp, c);
ptmp += c.GetLength();
len += c.GetLength();
size -= READBUFSIZE*3;
}else{
fread(in, sizeof(unsigned char), size, file);
to64frombits(out, in, size);
c = out;
c += "\r\n";
strcpy(ptmp, c);
ptmp += c.GetLength();
len += c.GetLength();
break;
}
}
tmp.ReleaseBuffer(len);
buf = tmp;
fclose(file);
return TRUE;
}
BOOL CMimeEncode::AddAttachedFile(CString path)
{
/* Content-Type: application/octet-stream; name=hogehoge
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=hogehoge*/
MULTIPART_STRUCT2 data;
data.m_encoding_type = "base64";
data.m_file_name = path.Mid(path.ReverseFind('\\')+1);
data.m_type = "application/octet-stream";
data.m_path = path;
data.m_content_type.Format("Content-Type: application/octet-stream; name=%s",
path.Mid(path.ReverseFind('\\')+1));
data.m_content_transfer_encoding = "Content-Transfer-Encoding: base64";
data.m_content_disposition.Format("Content-Disposition: attachment; filename=%s",
path.Mid(path.ReverseFind('\\')+1));
if(!this->EncodeBase64FromFile(path, data.m_body))
return FALSE;
m_data.m_multipart.Add(data);
return TRUE;
}
void CMimeEncode::AddPgpKey(CString key)
{
MULTIPART_STRUCT2 data;
data.m_content_type = "Content-Type: application/pgp-keys";
data.m_body = key;
m_data.m_multipart.Add(data);
}
void CMimeEncode::AddPgpEncrypted(CString enc)
{
SetMode(ME_MODE_PGP);
m_data.m_multipart.RemoveAll();
MULTIPART_STRUCT2 data;
data.m_content_type = "Content-Type: application/pgp-encrypted";
data.m_content_transfer_encoding = "Content-Transfer-Encoding: 7bit";
data.m_body = "Version: 1\r\n";
m_data.m_multipart.Add(data);
data.m_content_type = "Content-Type: application/octet-stream";
data.m_content_transfer_encoding = "Content-Transfer-Encoding: 7bit";
data.m_body = enc;
m_data.m_multipart.Add(data);
}
void CMimeEncode::AddText(CString body)
{
/* Content-Type: text/plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit*/
MULTIPART_STRUCT2 data;
data.m_encoding_type = "7bit";
data.m_type = "text/plain";
data.m_content_type = "Content-Type: Text/Plain; charset=ISO-2022-JP";
data.m_content_transfer_encoding = "Content-Transfer-Encoding: 7bit";
data.m_body = body;
m_data.m_multipart.Add(data);
}
void CMimeEncode::RemoveMultipart(int part)
{
m_data.m_multipart.RemoveAt(part);
}
void CMimeEncode::AddRFC822(CString mail)
{
}
CString CMimeEncode::GetCT(int part)
{
return m_data.m_multipart[part].m_content_type;
}
CString CMimeEncode::GetCD(int part)
{
return m_data.m_multipart[part].m_content_disposition;
}
CString CMimeEncode::GetCTE(int part)
{
return m_data.m_multipart[part].m_content_transfer_encoding;
}
CString CMimeEncode::GetBody(int part)
{
return m_data.m_multipart[part].m_body;
}
void CMimeEncode::SetMode(int mime_mode)
{
m_mime_mode = mime_mode;
}
int CMimeEncode::GetMode()
{
return m_mime_mode;
}
BOOL CMimeEncode::EncodeBase64(CString &out, CString in)
{
return TRUE;
}