📄 mailserver2client.cpp
字号:
/*
* Copyright (C) 2003-2007 Funambol, Inc
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY, TITLE, NONINFRINGEMENT or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
#include "pim/mail/MailServer2Client.h"
#include "base/util/utils.h"
#include "base/util/BasicTime.h"
#include "pim/difftime.h"
#include "pim/FILEServer2Client.h"
#include "base/Log.h"
#include "string.h"
#include <algorithm>
#include <vector>
#include "customization.h"
using namespace std;
HRESULT SetReplyTo(LPMAPISESSION lpSession, LPMESSAGE lpMessage, LPSTR pszReplyTo);
char* getMessageID(IMessage* pmsg, MailClientData* m);
//------------------------------------------------------------- Typedef
enum {
eeePR_ENTRYID,
eeePR_MESSAGE_FLAGS,
eeePR_LAST_MODIFICATION_TIME,
eeeNUM_COLS};
// These tags represent the message information we would like to pick up
static SizedSPropTagArray(eeeNUM_COLS, endSync) =
{
eeeNUM_COLS,
PR_ENTRYID, // entry id
PR_MESSAGE_FLAGS,
PR_LAST_MODIFICATION_TIME //
};
enum {
ePR_ENTRYID,
ePR_MESSAGE_FLAGS,
//MM
ePR_LAST_MODIFICATION_TIME,
ePR_SUBJECT,
ePR_SUBJECT_PREFIX,
ePR_MESSAGE_SIZE,
ePR_SENDER_NAME,
ePR_SENDER_EMAIL_ADDRESS,
ePR_HASATTACH,
//MM
NUM_COLS};
// These tags represent the message information we would like to pick up
static SizedSPropTagArray(NUM_COLS, properties) =
{
NUM_COLS,
PR_ENTRYID, // entry id
PR_MESSAGE_FLAGS,
//MM
PR_LAST_MODIFICATION_TIME, //
PR_SUBJECT, // mail Subject
PR_SUBJECT_PREFIX,
PR_MESSAGE_SIZE, // sum of the size of every property of the object
PR_SENDER_NAME, // "Marco "
PR_SENDER_EMAIL_ADDRESS, // From "Marco <magi@libero.it>
PR_HASATTACH
};
enum {
eePR_ENTRYID,
eePR_LAST_MODIFICATION_TIME,
eePR_DISPLAY_NAME,
eePR_MESSAGE_FLAGS,
eeNUM_COLS};
// These tags represent the message information we would like to pick up
static SizedSPropTagArray(eeNUM_COLS, Columns) =
{
eeNUM_COLS,
PR_ENTRYID,
PR_LAST_MODIFICATION_TIME,
PR_DISPLAY_NAME,
PR_MESSAGE_FLAGS
};
//----------------------------------------------------- Local functions
static ULONG CountRecipsInString(LPCWSTR psz)
{
ULONG cRecips = 0;
if (psz != NULL)
{
if (*psz != '\0')
++cRecips;
while (*psz != L'\0')
{
if (*psz == L';' || *psz == L',')
++cRecips;
++psz;
}
}
return cRecips;
}
//------------------------------------------------------ Constructors
MailServer2Client::MailServer2Client()
{
server_folderToSync = NULL;
}
MailServer2Client::~MailServer2Client()
{
if (server_folderToSync) {
delete [] server_folderToSync; server_folderToSync = NULL;
}
}
HRESULT MailServer2Client::deletePreviousAttachment(IMessage* pmsg) {
LOG.debug("Enter into deletePreviousAttachment function");
LPMAPITABLE pAttachTable = NULL;
// for each row in the attach table
LPSRowSet pRows = NULL;
HRESULT hr = pmsg->GetAttachmentTable(0, &pAttachTable);
EXIT_ON_FAILED(hr);
// iterate all the attachment
while(TRUE) {
hr = pAttachTable->QueryRows(1, 0, &pRows);
if (FAILED(hr) || pRows->cRows != 1)
break;
// only one row is returned anyway
int nProps = pRows->aRow[0].cValues;
long num = -1;
BOOL found = FALSE;
for (int i=0; i<nProps; i++) {
ULONG ulPT = pRows->aRow[0].lpProps[i].ulPropTag;
// TCHAR* szPropName = ReverseLookup(ulPT);
switch (ulPT) {
case PR_ATTACH_NUM:
num = pRows->aRow[0].lpProps[i].Value.ul;
found = TRUE;
break;
case PR_ATTACH_SIZE:
break;
case PR_ATTACH_FILENAME:
break;
case PR_MSG_STATUS:
break;
case 0x30000003:
// pRows->aRow[0].lpProps[ii].Value.ul: sequence number
break;
default:
break;
} // switch
if (found)
break;
}
FreeProws(pRows);
pmsg->DeleteAttach(num, NULL, 0, NULL);
}
FuncExit:
// Free each element in the pRows buffer
FreeProws(pRows);
RELEASE_OBJ(pAttachTable);
LOG.debug("Exiting from deletePreviousAttachment function");
return hr;
}
//----------------------------------------------------------- Methods
HRESULT MailServer2Client::AddAttachment(LPMESSAGE pmsg, MailClientData* m)
{
LOG.debug("Enter into AddAttachment function");
HRESULT hr = S_OK;
BodyPart* bodyPart = NULL;
bodyPart = m->getEmailData()->getEmailItem().getFirstAttachment();
if (bodyPart == NULL) {
LOG.debug("Exiting from AddAttachment function: no body part found");
return hr;
}
/*
* if the sync is inclusive, delete all the previous attachment because they comes
* new all from the current inclusive filter
*/
if (m->getIsSyncInclusive()) {
deletePreviousAttachment(pmsg);
}
do {
const char* tmpFileName = bodyPart->getContent();
if(!tmpFileName){
LOG.error("NULL temp file name from bodypart.");
hr = -1;
goto FuncExit;
}
wchar_t* filename = toWideChar(bodyPart->getFilename());
if (!filename) {
filename = createFileName(TEXT("noname"));
}
wchar_t* name = 0;
if (bodyPart->getName()) {
name = toWideChar(bodyPart->getName());
}
else {
name = wstrdup(filename);
}
/*
* Added extension to the name if there isn't one
*/
string mimeType(bodyPart->getMimeType());
std::transform(mimeType.begin(), mimeType.end(), mimeType.begin(), tolower);
if (mimeType.find("message/rfc822") != string::npos && wcsstr(name, TEXT(".eml")) == 0) {
wstring s(name);
s.append(TEXT(".eml"));
delete [] name;
name = wstrdup(s.c_str());
}
SPropValue prop[3];
IAttach* pAttachment = NULL;
ULONG ulAttachmentNum = 0;
FILE* fileAttach = NULL;;
memset(prop, 0, sizeof(prop));
fileAttach = fopen(tmpFileName, "rb");
if (fileAttach == NULL) {
LOG.error("AddAttachment: error opening input file");
hr = -1;
delete [] name;
delete [] filename;
continue;
}
hr = pmsg->CreateAttach(NULL, 0, &ulAttachmentNum, &pAttachment);
EXIT_ON_FAILED(hr);
// Set the initial properties on the attachment
// no data actually there yet
prop[0].ulPropTag = PR_ATTACH_METHOD;
prop[0].Value.ul = ATTACH_BY_VALUE;
prop[1].ulPropTag = PR_ATTACH_DATA_BIN;
prop[2].ulPropTag = PR_ATTACH_FILENAME;
prop[2].Value.LPSZ = name;
hr = pAttachment->SetProps(3, prop, NULL);
EXIT_ON_FAILED(hr);
// Now get the data property and fill it in
//
IStream* pStream;
hr = pAttachment->OpenProperty (PR_ATTACH_DATA_BIN,
NULL,
0,
MAPI_MODIFY | MAPI_CREATE,
(LPUNKNOWN *)&pStream);
EXIT_ON_FAILED(hr);
DWORD cbFile = fgetsize(fileAttach);
if (cbFile == 0xFFFFFFFF) {// error
LOG.error("AddAttachment: error loading temp file");
delete [] name;
delete [] filename;
continue;
}
ULONG cbWritten;
ULONG cbReadSize;
const ULONG ChunkSize = 4096;
BYTE Buffer[ChunkSize];
do {
cbReadSize = fread(Buffer, sizeof(BYTE), ChunkSize, fileAttach );
if (cbReadSize > 0) {
hr = pStream->Write(Buffer, cbReadSize, &cbWritten);
}
} while (!FAILED(hr) && (cbReadSize == ChunkSize));
fflush(fileAttach);
fclose(fileAttach);
pStream->Commit(STGC_DEFAULT);
pStream->Release();
// Set the size property
//
prop[0].ulPropTag = PR_ATTACH_SIZE;
prop[0].Value.ul = cbFile + sizeof(prop[2]);
hr = pAttachment->SetProps(1, prop, NULL);
if (tmpFileName != NULL) {
wchar_t* t = toWideChar(tmpFileName);
DeleteFile(t);
delete [] t;
}
delete [] name;
delete [] filename;
} while ((bodyPart = m->getEmailData()->getEmailItem().getNextAttachment()) != NULL);
FuncExit:
LOG.debug("Exiting from AddAttachment function");
return hr;
}
static TCHAR szSMTP[] = L"SMTP";
void AddRecipients(LPWSTR pszSrc, ULONG ulType, ADRLIST* plst, LPWSTR& pszLocalRecips, LPSPropValue& pval)
{
LOG.debug("Enter into AddRecipients function");
if (pszSrc == NULL) {
LOG.debug("Exiting from AddRecipients function: no recipients");
return;
}
LPWSTR psz = pszSrc;
while (*psz != L'\0') {
while (*psz == L' ' && *psz != '\0')
++psz;
if (*psz == L'\0')
break;
LPWSTR pszEnd = psz;
// while (*pszEnd != L' ' && (*pszEnd != ';' || *pszEnd != ',') && *pszEnd != '\0')
while (*pszEnd != ',' && *pszEnd != '\0')
++pszEnd;
int cch = pszEnd - psz;
wcsncpy(pszLocalRecips, psz, cch);
*(pszLocalRecips + cch) = L'\0';
plst->aEntries[plst->cEntries].cValues = 3;
plst->aEntries[plst->cEntries].rgPropVals = pval;
// Set the type (To, Cc, Bcc)...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -