root/MimeDecode.cpp
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- CMimeDecode
- CMimeDecode
- GetBody
- GetContentType
- GetEncodingType
- GetFileName
- GetRawCT
- GetRawCD
- GetRawCTE
- GetMultipartType
- HowManyPart
- IsMultipart
- GetHeaderEndPoint
- DoIt2
- DoIt
- AnalyzeMultiPart
- Initialize
- IsPgpMime
- GetCharSet
/*
* Copyright (C) 2002-2003 chik, s.hiranaka
* For license terms, see the file COPYING in this directory.
*/
// MimeDecode.cpp: CMimeDecode クラスのインプリメンテーション
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Pochy.h"
#include "MimeDecode.h"
#include <afxtempl.h> // CArrayテンプレートクラスに必要
#include "lib.h"
//////////////////////////////////////////////////////////////////////
// 構築/消滅
//////////////////////////////////////////////////////////////////////
CMimeDecode::CMimeDecode()
{
}
CMimeDecode::~CMimeDecode()
{
}
// partで指定されたmultipartのbodyをdst(CStringArray)へ書き込む
void CMimeDecode::GetBody(int part, CStringArray &dst)
{
int start;
int end;
start = m_data.GetAt(part).end_header+2;
end = m_data.GetAt(part).end;
g_cstra_getpart(m_mail, dst, start, end);
}
CString CMimeDecode::GetContentType(int part)
{
return m_data[part].content_type;
}
int CMimeDecode::GetEncodingType(int part)
{
return m_data[part].encoding_type;
}
CString CMimeDecode::GetFileName(int part)
{
return m_data[part].name;
}
CString CMimeDecode::GetRawCT(int part)
{
return m_data[part].raw_content_type;
}
CString CMimeDecode::GetRawCD(int part)
{
return m_data[part].raw_content_disposition;
}
CString CMimeDecode::GetRawCTE(int part)
{
return m_data[part].raw_content_transfer_encoding;
}
CString CMimeDecode::GetMultipartType()
{
CString buf;
int start;
int end;
if(IsMultipart()){
buf = m_hi.GetCT();
start = buf.Find("/")+1;
end = buf.Find(";", start);
return buf.Mid(start, end-start);
}
buf.Empty();
return buf;
}
int CMimeDecode::HowManyPart()
{
return m_data.GetSize();
}
BOOL CMimeDecode::IsMultipart()
{
return m_hi.IsMultipart();
}
BOOL CMimeDecode::GetHeaderEndPoint(CStringArray &mail, int &p)
{
int n = 0;
while(n < mail.GetSize()){
mail.GetAt(n);
if(mail.GetAt(n) == "\x0D\x0A"){
p = n-1;
break;
}
n++;
}
return TRUE;
}
BOOL CMimeDecode::DoIt2(CString mail)
{
Initialize();
int p = 0; // headerの終わり
g_cstr2cstra(mail, m_mail, "\r\n");
GetHeaderEndPoint(m_mail, p);
if(p == 0){
AfxMessageBox("メールが壊れてます(ヘッダが見当たりません)");
return FALSE;
}
CStringArray header;
g_cstra_getpart(m_mail, header, 0, p);
m_hi.DoIt(header);
MULTIPART_STRUCT data;
int n;
if(IsMultipart()){
if(!AnalyzeMultiPart(0, m_hi.GetBoundary())){
AfxMessageBox("MIMEの構造が変です");
return FALSE;
}
n = 0;
while(n < m_data.GetSize()){
if(!m_data.GetAt(n).boundary.IsEmpty())
if(!AnalyzeMultiPart(m_data.GetAt(n).start, m_data.GetAt(n).boundary)){
AfxMessageBox("MIMEの構造が変です");
return FALSE;
}
n++;
}
// multipart入れ子構造の親を削除
n = 0;
while(n < m_data.GetSize()){
if(!m_data.GetAt(n).boundary.IsEmpty()){
m_data.RemoveAt(n);
}
n++;
}
}else{
data.start = 0;
GetHeaderEndPoint(m_mail, p);
data.end_header = p;
data.end = m_mail.GetSize()-1;
data.name = m_hi.GetFilename();
if(data.name.IsEmpty())
data.name = m_hi.GetName();
data.content_type = m_hi.GetCType();
data.encoding_type = m_hi.GetEnc();
m_data.Add(data);
}
return TRUE;
}
BOOL CMimeDecode::DoIt(CString path)
{
Initialize();
CString message;
if(!g_is_there(path)){
message.Format("%s が存在しないため開けません", path);
AfxMessageBox(message);
message.Empty();
return FALSE;
}
int p = 0; // headerの終わり
CStringArray header;
g_file2cstra(path, m_mail);
GetHeaderEndPoint(m_mail, p);
if(p == 0){
AfxMessageBox("メールが壊れてます(ヘッダが見当たりません)");
return FALSE;
}
g_cstra_getpart(m_mail, header, 0, p);
m_hi.DoIt(header);
MULTIPART_STRUCT data;
int n;
if(IsMultipart()){
if(!AnalyzeMultiPart(0, m_hi.GetBoundary())){
AfxMessageBox("MIMEの構造が変です");
return FALSE;
}
n = 0;
while(n < m_data.GetSize()){
if(!m_data.GetAt(n).boundary.IsEmpty())
if(!AnalyzeMultiPart(m_data.GetAt(n).start, m_data.GetAt(n).boundary)){
AfxMessageBox("MIMEの構造が変です");
return FALSE;
}
n++;
}
// multipart入れ子構造の親を削除
n = 0;
while(n < m_data.GetSize()){
if(!m_data.GetAt(n).boundary.IsEmpty()){
m_data.RemoveAt(n);
}
n++;
}
}else{
data.start = 0;
GetHeaderEndPoint(m_mail, p);
data.end_header = p;
data.end = m_mail.GetSize()-1;
data.name = m_hi.GetFilename();
if(data.name.IsEmpty())
data.name = m_hi.GetName();
data.content_type = m_hi.GetCType();
data.encoding_type = m_hi.GetEnc();
data.raw_content_type = m_hi.GetCT();
data.raw_content_transfer_encoding = m_hi.GetCTE();
data.raw_content_disposition = m_hi.GetCD();
m_data.Add(data);
}
return TRUE;
}
BOOL CMimeDecode::AnalyzeMultiPart(int start, CString boundary)
{
int n1;
int n2;
int p;
CUIntArray ia;
CHeaderInfo hi;
CStringArray part;
CString sep = "--"+boundary+"\r\n";
CString last = "--"+boundary+"--"+"\r\n";
CStringArray pheader;
MULTIPART_STRUCT data;
n1 = start;
while(n1 < m_mail.GetSize()){
if(m_mail.GetAt(n1) == sep){
ia.Add(n1);
n1++;
continue;
}
if(m_mail.GetAt(n1) == last){
ia.Add(n1);
break;
}
n1++;
}
if(ia.GetSize() < 2)
return FALSE;
n2 = 0;
while(n2+1 < ia.GetSize()){
g_cstra_getpart(m_mail, part, ia.GetAt(n2)+1, ia.GetAt(n2+1)-1);
GetHeaderEndPoint(part, p);
g_cstra_getpart(m_mail, pheader, ia.GetAt(n2)+1, ia.GetAt(n2)+1+p);
hi.DoIt(pheader);
data.start = ia.GetAt(n2)+1;
data.end_header = data.start+p;
data.end = ia.GetAt(n2+1)-1;
data.boundary = hi.GetBoundary();
data.content_type = hi.GetCType();
data.encoding_type = hi.GetEnc();
data.name = hi.GetFilename();
if(data.name.IsEmpty())
data.name = hi.GetName();
data.raw_content_type = hi.GetCT();
data.raw_content_transfer_encoding = hi.GetCTE();
data.raw_content_disposition = hi.GetCD();
m_data.Add(data);
n2++;
}
return TRUE;
}
void CMimeDecode::Initialize()
{
// 変数の初期化
m_data.RemoveAll();
m_mail.RemoveAll();
}
BOOL CMimeDecode::IsPgpMime()
{
return g_cstr_compare(m_hi.GetProtocol(), "application/pgp-encrypted");
}
CString CMimeDecode::GetCharSet()
{
return m_hi.GetCharset();
}