// frmActivityMgr.cpp - Activity Manager form.
//
// (c) 2012-2015 Xestia Software Development.
//
// This file is part of Xestia Address Book.
//
// Xestia Address Book is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by the
// Free Software Foundation, version 3 of the license.
//
// Xestia Address Book is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY 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 Xestia Address Book. If not, see
#include "frmActivityMgr.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "../bitmaps.h"
#include "../enums.h"
#include "../common/preferences.h"
#include "../frmConflictResolution.h"
#include "../frmInvalidSSLCertificate.h"
#include "../frmMain.h"
#include "../common/events.h"
#include "../common/filename.h"
#include "../vcard/vcard34conv.h"
#include "../vcard/vcard.h"
DEFINE_EVENT_TYPE(ACTMGR_RESUMEPROC);
DEFINE_EVENT_TYPE(ACTMGR_TOGGLECONN);
DEFINE_EVENT_TYPE(ACTMGR_STARTTIMER);
DEFINE_EVENT_TYPE(ACTMGR_STOPTIMER);
DEFINE_EVENT_TYPE(ACTMGR_STARTPROCESSTIMER);
DEFINE_EVENT_TYPE(ACTMGR_STOPPROCESSTIMER);
DEFINE_EVENT_TYPE(ACTMGR_UPDATESTATUSLABEL);
DEFINE_EVENT_TYPE(ACTMGR_STARTANIMATIONTIMER);
BEGIN_EVENT_TABLE(frmActivityMgr, wxWindow)
EVT_COMMAND(wxID_ANY, ACTMGR_RESUMEPROC, frmActivityMgr::ResumeProcessing)
EVT_COMMAND(wxID_ANY, ACTMGR_TOGGLECONN, frmActivityMgr::ToggleConnectionStatus)
EVT_COMMAND(wxID_ANY, ACTMGR_STARTTIMER, frmActivityMgr::StartTimer)
EVT_COMMAND(wxID_ANY, ACTMGR_STOPTIMER, frmActivityMgr::StopTimer)
EVT_COMMAND(wxID_ANY, ACTMGR_STARTPROCESSTIMER, frmActivityMgr::StartProcessTimer)
EVT_COMMAND(wxID_ANY, ACTMGR_STOPPROCESSTIMER, frmActivityMgr::StopProcessTimer)
EVT_COMMAND(wxID_ANY, ACTMGR_UPDATESTATUSLABEL, frmActivityMgr::UpdateStatusLabel)
EVT_COMMAND(wxID_ANY, ACTMGR_STARTANIMATIONTIMER, frmActivityMgr::StartAnimationTimer)
END_EVENT_TABLE()
frmActivityMgr::frmActivityMgr( wxWindow* parent )
:
frmActivityMgrADT( parent )
{
wxMemoryInputStream istream(icons_activitywindow_png, sizeof(icons_activitywindow_png));
wxImage icons_activitywindow_pngi(istream, wxBITMAP_TYPE_PNG);
wxBitmap activityiconbmp(icons_activitywindow_pngi, -1);
wxIcon activityicon;
activityicon.CopyFromBitmap(activityiconbmp);
this->SetIcon(activityicon);
wxMemoryInputStream istream2(misc_activitysleep_png, sizeof(misc_activitysleep_png));
wxImage misc_activitysleep_pngi(istream2, wxBITMAP_TYPE_PNG);
wxBitmap sleepiconbmp(misc_activitysleep_pngi, -1);
SleepBitmap = sleepiconbmp;
bmpActivity->SetBitmap(SleepBitmap);
ActProcessTimer.SetupPointers(this);
lblDetails->SetLabel(_("No activity."));
ActListProcTimer.SetupPointers(&ActivityList, &ActivityListIndex, &ActivityListTaskDetail,
&TasksActive, lstActivity, lblDetails, GauProgress, this, &AnimationTimer,
&ActProcessTimer, &ActivityListFinDate, &ActivityListConnObject);
AnimationTimer.SetBitmap(bmpActivity);
AnimationTimer.SetSleepBitmap(&SleepBitmap);
AnimationTimer.SetupPointer(this->GetParent());
wxListItem ColumnData;
ColumnData.SetId(0);
ColumnData.SetText(_("Activity"));
ColumnData.SetWidth(175);
lstActivity->InsertColumn(0, ColumnData);
wxListItem ColumnData2;
ColumnData2.SetId(1);
ColumnData2.SetText(_("Account"));
ColumnData2.SetWidth(100);
lstActivity->InsertColumn(1, ColumnData2);
wxListItem ColumnData3;
ColumnData3.SetId(2);
ColumnData3.SetText(_("Status"));
ColumnData3.SetWidth(100);
lstActivity->InsertColumn(2, ColumnData3);
//AnimationTimer.StartAnimation();
// Create recovery database if it doesn't exist.
wxString RecoveryFilename = GetRecoveryDB();
wxFile RecoveryDB;
if (wxFile::Exists(RecoveryFilename) == FALSE){
// Create the recovery database.
RecoveryDB.Open(RecoveryFilename.c_str(), wxFile::write);
RecoveryDB.Write(wxT("BEGIN:XAB-RECOVERYDB\r\n"), wxConvUTF8);
RecoveryDB.Write(wxT("VERSION:1.0\r\n"), wxConvUTF8);
RecoveryDB.Write(wxT("COMMENT:Please do not alter or delete this file. DATA LOSS IS POSSIBLE!\r\n"), wxConvUTF8);
RecoveryDB.Write(wxT("END:XAB-RECOVERYDB\r\n"), wxConvUTF8);
RecoveryDB.Close();
}
wxFFile RecoveryDBF;
#if wxABI_VERSION < 20900
RecoveryDBF.Open(RecoveryFilename.c_str(), wxT("r"));
#else
RecoveryDBF.Open(RecoveryFilename, wxT("r"));
#endif
// Load the recovery database for tasks not done.
if (RecoveryDBF.IsOpened() == TRUE){
wxString wxSRecoveryDB;
wxString RecoveryLine;
// Check if we are using wxWidgets version 2.8 or less and
// execute the required command accordingly.
RecoveryDBF.ReadAll(&wxSRecoveryDB, wxConvAuto());
// Split the lines.
std::map RecoveryFileLines;
std::map::iterator striter;
wxStringTokenizer wSTRecoveryDBLines(wxSRecoveryDB, wxT("\r\n"));
int RecoveryLineSeek = 0;
while (wSTRecoveryDBLines.HasMoreTokens() == TRUE){
RecoveryLine = wSTRecoveryDBLines.GetNextToken();
RecoveryFileLines.insert(std::make_pair(RecoveryLineSeek, RecoveryLine));
RecoveryLineSeek++;
}
}
//TestTimer.Start(50, FALSE);
}
void frmActivityMgr::OpenWindow()
{
WindowOpen = TRUE;
}
void frmActivityMgr::CloseWindow( wxCommandEvent& event )
{
WindowOpen = FALSE;
this->Hide();
}
void frmActivityMgr::CloseWindow( wxCloseEvent& event )
{
WindowOpen = FALSE;
this->Hide();
}
void frmActivityMgr::ProcessTasksThread()
{
if (ProcessTasksData == FALSE){
return;
}
if (ApplicationSleepMode == TRUE){
return;
}
std::map::iterator TypeIter;
std::map::iterator StringIter;
std::map::iterator StringDataIter;
std::map::iterator StringURLIter;
std::map::iterator StringDetailIter;
std::map::iterator StringAccountIter;
std::map::iterator StringFilenameIter;
std::map::iterator StringFullFilenameIter;
std::map::iterator StringTaskDetailIter;
std::map::iterator StringETagIter;
std::map::iterator StringETagOrigIter;
std::map::iterator ConnObjectIter;
std::map::iterator AccountSettingsIter;
std::map::iterator LongIter;
bool TasksFoundProc = FALSE;
wxString TaskDetail;
for (std::map::iterator iter = ActivityList.begin();
iter != ActivityList.end(); ++iter){
// Check for any queued tasks and start one.
if (iter->second > 4){
continue;
}
wxCommandEvent StartAnimationEvent(ACTMGR_STARTANIMATIONTIMER);
wxPostEvent(this, StartAnimationEvent);
// Start the animation timer if it hasn't started.
ConnObjectIter = ActivityListConnObject.find(iter->first);
TypeIter = ActivityListType.find(iter->first);
StringETagIter = ActivityListETag.find(iter->first);
StringETagOrigIter = ActivityListETagOriginal.find(iter->first);
StringAccountIter = ActivityListAccount.find(iter->first);
StringFilenameIter = ActivityListFilename.find(iter->first);
StringFullFilenameIter = ActivityListFullFilename.find(iter->first);
AccountSettingsIter = ActivityListAccSettings.find(iter->first);
// Setup the CardDAV object.
// 0 = Queued.
// 1 = Processing.
// 2 = Failed.
// 3 = Stopped.
// 4 = Completed.
// 5 = Failed (UI Updated).
// 6 = Stopped (UI Updated).
// 7 = (Reserved) (UI Updated).
// 8 = Completed. (UI Updated).
frmMain *frmMainPtrGet = static_cast(frmMainPtr);
XABPreferences PrefData(GetUserPrefDir());
if (iter->second == 0){
// Wait for process to finish.
TasksActive = TRUE;
TasksFoundProc = TRUE;
wxString ETag;
wxString ETagOriginal;
wxString ETagServer;
wxString AccountDir;
wxString ContactFilename;
wxString FullFilename;
wxString ETagResult;
bool EditMode = FALSE;
iter->second = 1;
// Compare the ETags and work out if a conflict has occured.
if (TypeIter->second == 0){
// Add a contact.
StringDataIter = ActivityListData.find(iter->first);
StringURLIter = ActivityListURL.find(iter->first);
AccountDir = StringAccountIter->second;
ContactFilename = StringFilenameIter->second;
wxString AccountNameFriendly;
int AccountID = 0;
for (int i = 0; i < PrefData.accounts.GetCount(); i++){
wxString AccountDirCheck = PrefData.accounts.GetAccountDirectory(i);
AccountDirCheck.Trim();
AccountDirCheck.Append(wxT(".carddav"));
if (AccountDirCheck == StringAccountIter->second){
AccountNameFriendly = PrefData.accounts.GetAccountName(i);
AccountID = i;
}
}
ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
ETag = StringETagIter->second;
ETagOriginal = StringETagOrigIter->second;
AccountDir = StringAccountIter->second;
ContactFilename = StringFilenameIter->second;
FullFilename = StringFullFilenameIter->second;
EditMode = ActivityListEditMode.find(iter->first)->second;
bool KeepUpdating = true;
while(KeepUpdating == true){
COConnectResult ConnectResponse = ConnObjectIter->second->Connect(false);
bool ExitLoop = false;
while (ExitLoop == false){
if (ConnObjectIter->second->SSLVerify() == COSSL_UNABLETOVERIFY){
frmMainPtrGet->PauseAllTimers();
#if defined(__APPLE__)
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult ConnectionSSLResult = ConnObjectIter->second->Connect(false);
ConnObjectIter->second->BypassSSLVerification(false);
int SSLResult = DisplayTrustPanel(ConnObjectIter->second->BuildSSLCollection(), AccountNameFriendly);
if (SSLResult != NSOKButton){
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 1, ConnObjectIter->second->BuildSSLCollection());
iter->second = 2;
break;
} else {
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
}
#elif defined(__WIN32__)
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult ConnectionSSLResult = ConnObjectIter->second->Connect(false);
ConnObjectIter->second->BypassSSLVerification(false);
BOOL ModifiedCertificateData = false;
CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(ConnObjectIter->second, (HWND)frmMainPtrGet->GetHandle());
if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)) {
wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
}
if (ModifiedCertificateData == false) {
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 1, ConnObjectIter->second->BuildSSLCollection());
iter->second = 2;
break;
} else {
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
}
#else
bool UsingSSLBypass = false;
int SSLResult = 0;
// Connect again and fetch SSL certificate information.
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult ConnectionSSLResult = ConnObjectIter->second->Connect(false);
ConnObjectIter->second->BypassSSLVerification(false);
SSLInvalidCertNotifObjString SSLICNProcData;
SSLCertCollectionString certcol = ConnObjectIter->second->BuildSSLCollection();
bool *PauseMode = new bool;
QRNotif qrn;
*PauseMode = TRUE;
qrn.QResponse = &SSLResult;
qrn.PausePtr = PauseMode;
SSLICNProcData.CertCollection = certcol;
SSLICNProcData.QRNotifData = &qrn;
SSLICNProcData.AccountName = AccountNameFriendly;
wxCommandEvent event(INVALIDSSLCERTSTRING);
event.SetClientData(&SSLICNProcData);
wxPostEvent(frmMainPtrGet, event);
while (*PauseMode == TRUE){
//nanosleep(&n1, &n2);
SleepFor(250000000);
}
// Process the response from the user.
if (SSLResult == 1){
// Accept the Certificate.
UsingSSLBypass = true;
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult TestConnectionResult = ConnObjectIter->second->Connect(true);
WriteServerCertificate(AccountDir, certcol);
ConnObjectIter->second->BypassSSLVerification(false);
} else if (SSLResult == 2){
// Reject the certificate, abort the task and mark as failed.
iter->second = 2;
break;
}
#endif
frmMainPtrGet->ResumeAllTimers();
ExitLoop = true;
} else if (ConnectResponse == COCONNECT_AUTHFAIL){
ConnectResponse = ConnObjectIter->second->Connect(true);
if (ConnectResponse == COCONNECT_OK){
ExitLoop = true;
break;
} else {
ExitLoop = true;
iter->second = 2;
break;
}
} else if (ConnectResponse == COCONNECT_OK){
ConnectResponse = ConnObjectIter->second->Connect(true);
ExitLoop = true;
break;
} else {
ExitLoop = true;
iter->second = 2;
break;
}
}
if (iter->second == 2 || iter->second == 3 || iter->second == 4){
break;
}
#if defined(__APPLE__)
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
#elif defined(__WIN32__)
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
#else
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
#endif
COServerResponse AddContactResponse = ConnObjectIter->second->AddContact(StringURLIter->second.ToStdString(),
std::string(StringDataIter->second.ToUTF8()));
if (AddContactResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
// Get the entity tag for the new contact.
COServerResponse ETagGetResponse = ConnObjectIter->second->GetServerEntityTagValue(StringURLIter->second.ToStdString());
if (ETagGetResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
ETagDBPtr->UpdateETag(ContactFilename, ETagGetResponse.EntityTag, ETagGetResponse.EntityTag);
iter->second = 4;
break;
}
} else if (TypeIter->second == 1){
// Update a contact.
StringDataIter = ActivityListData.find(iter->first);
StringURLIter = ActivityListURL.find(iter->first);
AccountDir = StringAccountIter->second;
ContactFilename = StringFilenameIter->second;
wxString AccountNameFriendly;
int AccountID = 0;
for (int i = 0; i < PrefData.accounts.GetCount(); i++){
wxString AccountDirCheck = PrefData.accounts.GetAccountDirectory(i);
AccountDirCheck.Trim();
AccountDirCheck.Append(wxT(".carddav"));
if (AccountDirCheck == StringAccountIter->second){
AccountNameFriendly = PrefData.accounts.GetAccountName(i);
AccountID = i;
}
}
ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
ETag = StringETagIter->second;
ETagOriginal = StringETagOrigIter->second;
AccountDir = StringAccountIter->second;
ContactFilename = StringFilenameIter->second;
FullFilename = StringFullFilenameIter->second;
EditMode = ActivityListEditMode.find(iter->first)->second;
bool KeepUpdating = true;
while(KeepUpdating == true){
COConnectResult ConnectResponse = ConnObjectIter->second->Connect(false);
bool ExitLoop = false;
while(ExitLoop == false){
if (ConnObjectIter->second->SSLVerify() == COSSL_UNABLETOVERIFY){
frmMainPtrGet->PauseAllTimers();
#if defined(__APPLE__)
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult ConnectionSSLResult = ConnObjectIter->second->Connect(false);
ConnObjectIter->second->BypassSSLVerification(false);
int SSLResult = DisplayTrustPanel(ConnObjectIter->second->BuildSSLCollection(), AccountNameFriendly);
if (SSLResult != NSOKButton){
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 1, ConnObjectIter->second->BuildSSLCollection());
iter->second = 2;
break;
} else {
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
}
#elif defined(__WIN32__)
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult ConnectionSSLResult = ConnObjectIter->second->Connect(false);
ConnObjectIter->second->BypassSSLVerification(false);
BOOL ModifiedCertificateData = false;
CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(ConnObjectIter->second, (HWND)frmMainPtrGet->GetHandle());
if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)) {
wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
}
if (ModifiedCertificateData == FALSE) {
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 1, ConnObjectIter->second->BuildSSLCollection());
iter->second = 2;
break;
} else {
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
}
#else
bool UsingSSLBypass = false;
int SSLResult = 0;
// Connect again and fetch SSL certificate information.
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult ConnectionSSLResult = ConnObjectIter->second->Connect(false);
ConnObjectIter->second->BypassSSLVerification(false);
SSLInvalidCertNotifObjString SSLICNProcData;
SSLCertCollectionString certcol = ConnObjectIter->second->BuildSSLCollection();
bool *PauseMode = new bool;
QRNotif qrn;
*PauseMode = TRUE;
qrn.QResponse = &SSLResult;
qrn.PausePtr = PauseMode;
SSLICNProcData.CertCollection = certcol;
SSLICNProcData.QRNotifData = &qrn;
SSLICNProcData.AccountName = AccountNameFriendly;
wxCommandEvent event(INVALIDSSLCERTSTRING);
event.SetClientData(&SSLICNProcData);
wxPostEvent(frmMainPtrGet, event);
while (*PauseMode == TRUE){
SleepFor(250000000);
}
// Process the response from the user.
if (SSLResult == 1){
// Accept the Certificate.
UsingSSLBypass = true;
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult TestConnectionResult = ConnObjectIter->second->Connect(true);
WriteServerCertificate(AccountDir, certcol);
ConnObjectIter->second->BypassSSLVerification(false);
} else if (SSLResult == 2){
// Reject the certificate, abort the task and mark as failed.
iter->second = 2;
break;
}
#endif
frmMainPtrGet->ResumeAllTimers();
ExitLoop = true;
} else if (ConnectResponse == COCONNECT_AUTHFAIL){
ConnectResponse = ConnObjectIter->second->Connect(true);
if (ConnectResponse == COCONNECT_OK){
ExitLoop = true;
break;
} else {
ExitLoop = true;
iter->second = 2;
break;
}
} else if (ConnectResponse == COCONNECT_OK){
ConnectResponse = ConnObjectIter->second->Connect(true);
ExitLoop = true;
break;
} else {
ExitLoop = true;
iter->second = 2;
break;
}
}
if (iter->second == 2 || iter->second == 3 || iter->second == 4){
break;
}
COServerResponse ETagGetResponse = ConnObjectIter->second->GetServerEntityTagValue(StringURLIter->second.ToStdString());
if (ETagGetResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
ETagServer = ETagGetResponse.EntityTag;
// Compare the ETag with the Server ETag.
if (ETagOriginal != ETagServer){
// Server ETag is different from original ETag.
// This is a conflict which the user will now
// need to resolve.
frmMain *frmMainPtrGet = static_cast(frmMainPtr);
vCard34Conv vCard34Obj;
std::string ServerContactData;
wxString wxStringServerContactData;
vCard ClientData;
vCard ConvertedV4Data;
// Load the client data from the filename given.
COServerResponse GetContactResponse = ConnObjectIter->second->GetContact(StringURLIter->second.ToStdString(),
&ServerContactData);
if (GetContactResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
wxStringServerContactData = wxString::FromUTF8((const char*)ServerContactData.c_str());
// Process v3 version into v4 version.
vCard34Obj.ConvertToV4(&wxStringServerContactData, &ConvertedV4Data);
vCardConflictObj vCardProcData;
vCardProcData.vCardLocalData = &ClientData;
vCardProcData.vCardServerData = &ConvertedV4Data;
ClientData.LoadFile(FullFilename);
// Setup Conflict Resolution Dialog.
// Fetch Data from Server and convert.
bool *PauseMode = new bool;
int ConflictResult;
QRNotif qrn;
*PauseMode = TRUE;
qrn.QResponse = &ConflictResult;
qrn.PausePtr = PauseMode;
vCardProcData.QRNotifData = &qrn;
wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
event.SetClientData(&vCardProcData);
wxPostEvent(frmMainPtrGet, event);
while (*PauseMode == TRUE){
SleepFor(250000000);
}
delete PauseMode;
PauseMode = NULL;
if (ConflictResult == 0){
// Decide Later.
iter->second = 4;
break;
} else if (ConflictResult == 1){
// Decided to use client version.
} else if (ConflictResult == 2){
// Decided to use server version.
// Download server version.
ConvertedV4Data.WriteFile(FullFilename);
}
} else {
// Upload the data to the server.
COServerResponse EditContactResponse = ConnObjectIter->second->EditContact(StringURLIter->second.ToStdString(),
std::string(StringDataIter->second.ToUTF8()));
if (EditContactResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
}
ETagGetResponse = ConnObjectIter->second->GetServerEntityTagValue(StringURLIter->second.ToStdString());
if (ETagGetResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
ETagDBPtr->UpdateETag(ContactFilename, ETagGetResponse.EntityTag, ETagGetResponse.EntityTag);
iter->second = 4;
break;
}
} else if (TypeIter->second == 2) {
// Delete the contact from the server and update the ETag DB.
AccountDir = StringAccountIter->second;
ContactFilename = StringFilenameIter->second;
wxString AccountNameFriendly;
int AccountID = 0;
for (int i = 0; i < PrefData.accounts.GetCount(); i++){
wxString AccountDirCheck = PrefData.accounts.GetAccountDirectory(i);
AccountDirCheck.Trim();
AccountDirCheck.Append(wxT(".carddav"));
if (AccountDirCheck == StringAccountIter->second){
AccountNameFriendly = PrefData.accounts.GetAccountName(i);
AccountID = i;
}
}
ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
bool KeepUpdating = TRUE;
while(KeepUpdating == TRUE){
COConnectResult ConnectResponse = ConnObjectIter->second->Connect(false);
bool ExitLoop = FALSE;
while (ExitLoop == FALSE){
if (ConnObjectIter->second->SSLVerify() == COSSL_UNABLETOVERIFY){
frmMainPtrGet->PauseAllTimers();
#if defined(__APPLE__)
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult ConnectionSSLResult = ConnObjectIter->second->Connect(false);
ConnObjectIter->second->BypassSSLVerification(false);
int SSLResult = DisplayTrustPanel(ConnObjectIter->second->BuildSSLCollection(), AccountNameFriendly);
if (SSLResult != NSOKButton){
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 1, ConnObjectIter->second->BuildSSLCollection());
iter->second = 2;
break;
} else {
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
}
#elif defined(__WIN32__)
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult ConnectionSSLResult = ConnObjectIter->second->Connect(false);
ConnObjectIter->second->BypassSSLVerification(false);
BOOL ModifiedCertificateData = false;
CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(ConnObjectIter->second, (HWND)frmMainPtrGet->GetHandle());
if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)) {
wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
}
if (ModifiedCertificateData == false) {
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 1, ConnObjectIter->second->BuildSSLCollection());
iter->second = 2;
break;
} else {
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
}
#else
bool UsingSSLBypass = false;
int SSLResult = 0;
// Connect again and fetch SSL certificate information.
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult ConnectionSSLResult = ConnObjectIter->second->Connect(false);
ConnObjectIter->second->BypassSSLVerification(false);
SSLInvalidCertNotifObjString SSLICNProcData;
SSLCertCollectionString certcol = ConnObjectIter->second->BuildSSLCollection();
bool *PauseMode = new bool;
QRNotif qrn;
*PauseMode = TRUE;
qrn.QResponse = &SSLResult;
qrn.PausePtr = PauseMode;
SSLICNProcData.CertCollection = certcol;
SSLICNProcData.QRNotifData = &qrn;
SSLICNProcData.AccountName = AccountNameFriendly;
wxCommandEvent event(INVALIDSSLCERTSTRING);
event.SetClientData(&SSLICNProcData);
wxPostEvent(frmMainPtrGet, event);
while (*PauseMode == TRUE){
//nanosleep(&n1, &n2);
SleepFor(250000000);
}
// Process the response from the user.
if (SSLResult == 1){
// Accept the Certificate.
UsingSSLBypass = true;
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult TestConnectionResult = ConnObjectIter->second->Connect(true);
WriteServerCertificate(AccountDir, certcol);
ConnObjectIter->second->BypassSSLVerification(false);
} else if (SSLResult == 2){
// Reject the certificate, abort the task and mark as failed.
iter->second = 2;
break;
}
#endif
frmMainPtrGet->ResumeAllTimers();
ExitLoop = true;
} else if (ConnectResponse == COCONNECT_AUTHFAIL){
ConnectResponse = ConnObjectIter->second->Connect(true);
if (ConnectResponse == COCONNECT_OK){
ExitLoop = true;
break;
} else {
ExitLoop = true;
iter->second = 2;
break;
}
} else if (ConnectResponse == COCONNECT_OK){
ConnectResponse = ConnObjectIter->second->Connect(true);
ExitLoop = true;
break;
} else {
ExitLoop = true;
iter->second = 2;
break;
}
}
if (iter->second == 2 || iter->second == 3 || iter->second == 4){
break;
}
#if defined(__APPLE__)
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
#elif defined(__WIN32__)
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
#else
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
#endif
COServerResponse DeleteContactResponse = ConnObjectIter->second->DeleteContact(ContactFilename.ToStdString());
if (DeleteContactResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
ETagDBPtr->RemoveETag(ContactFilename);
iter->second = 4;
break;
}
} else if (TypeIter->second == 3) {
wxString AccountNameFriendly;
int AccountID = 0;
for (int i = 0; i < PrefData.accounts.GetCount(); i++){
wxString AccountDirCheck = PrefData.accounts.GetAccountDirectory(i);
AccountDirCheck.Trim();
AccountDirCheck.Append(wxT(".carddav"));
if (AccountDirCheck == StringAccountIter->second){
AccountNameFriendly = PrefData.accounts.GetAccountName(i);
AccountID = i;
}
}
bool KeepUpdating = TRUE;
while (KeepUpdating == TRUE){
StringTaskDetailIter = ActivityListTaskDetail.find(iter->first);
AccountDir = StringAccountIter->second;
ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
wxArrayString vCardAdd;
wxArrayString vCardDelete;
wxArrayString vCardList;
wxArrayString vCardUpdateLocal;
wxArrayString vCardUpdateRemote;
wxArrayString vCardUpdateLog;
std::map vCardETag;
std::map vCardDownloadData;
// Get the list of vCard files locally.
wxString AccountDirFinal;
wxString AccountSyncTokenFilename;
wxString SyncTokenLoad;
#if defined(__HAIKU__)
//preffilename = wxT("noo");
#elif defined(__WIN32__)
AccountDirFinal = GetAccountDir(AccountDir, FALSE);
AccountSyncTokenFilename = AccountDirFinal;
AccountSyncTokenFilename.Append(wxT("synctoken"));
#else
AccountDirFinal = GetAccountDir(AccountDir, FALSE);
AccountSyncTokenFilename = AccountDirFinal;
AccountSyncTokenFilename.Append(wxT("synctoken"));
#endif
// Suppress Error Messages.
wxLogNull PleaseDoNotDisturb;
wxFFile SyncLoad;
SyncLoad.Open(AccountSyncTokenFilename, wxT("r"));
if (SyncLoad.IsOpened()){
SyncLoad.ReadAll(&SyncTokenLoad, wxMBConvUTF8());
SyncLoad.Close();
}
// Get a list of vCard files from the server.
// Get the list of vCard files from the ETagDB.
std::map ETagDBData = ETagDBPtr->GetETagData();
COConnectResult ConnectResponse = ConnObjectIter->second->Connect(false);
bool ExitLoop = FALSE;
while (ExitLoop == FALSE){
if (ConnObjectIter->second->SSLVerify() == COSSL_UNABLETOVERIFY){
frmMainPtrGet->PauseAllTimers();
#if defined(__APPLE__)
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult ConnectionSSLResult = ConnObjectIter->second->Connect(false);
ConnObjectIter->second->BypassSSLVerification(false);
int SSLResult = DisplayTrustPanel(ConnObjectIter->second->BuildSSLCollection(), AccountNameFriendly);
if (SSLResult != NSOKButton){
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 1, ConnObjectIter->second->BuildSSLCollection());
iter->second = 2;
break;
} else {
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
}
#elif defined(__WIN32__)
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult ConnectionSSLResult = ConnObjectIter->second->Connect(false);
ConnObjectIter->second->BypassSSLVerification(false);
BOOL ModifiedCertificateData = false;
CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(ConnObjectIter->second, (HWND)frmMainPtrGet->GetHandle());
if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)) {
wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
}
if (ModifiedCertificateData == false) {
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 1, ConnObjectIter->second->BuildSSLCollection());
iter->second = 2;
break;
} else {
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
}
#else
bool UsingSSLBypass = false;
int SSLResult = 0;
// Connect again and fetch SSL certificate information.
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult ConnectionSSLResult = ConnObjectIter->second->Connect(false);
ConnObjectIter->second->BypassSSLVerification(false);
SSLInvalidCertNotifObjString SSLICNProcData;
SSLCertCollectionString certcol = ConnObjectIter->second->BuildSSLCollection();
bool *PauseMode = new bool;
QRNotif qrn;
*PauseMode = TRUE;
qrn.QResponse = &SSLResult;
qrn.PausePtr = PauseMode;
SSLICNProcData.CertCollection = certcol;
SSLICNProcData.QRNotifData = &qrn;
SSLICNProcData.AccountName = AccountNameFriendly;
wxCommandEvent event(INVALIDSSLCERTSTRING);
event.SetClientData(&SSLICNProcData);
wxPostEvent(frmMainPtrGet, event);
while (*PauseMode == TRUE){
//nanosleep(&n1, &n2);
SleepFor(250000000);
}
// Process the response from the user.
if (SSLResult == 1){
// Accept the Certificate.
UsingSSLBypass = true;
ConnObjectIter->second->BypassSSLVerification(true);
COConnectResult TestConnectionResult = ConnObjectIter->second->Connect(true);
WriteServerCertificate(AccountDir, certcol);
ConnObjectIter->second->BypassSSLVerification(false);
} else if (SSLResult == 2){
// Reject the certificate, abort the task and mark as failed.
iter->second = 2;
break;
}
#endif
frmMainPtrGet->ResumeAllTimers();
ExitLoop = true;
} else if (ConnectResponse == COCONNECT_AUTHFAIL){
ConnectResponse = ConnObjectIter->second->Connect(true);
if (ConnectResponse == COCONNECT_OK){
ExitLoop = true;
break;
} else {
ExitLoop = true;
iter->second = 2;
break;
}
} else if (ConnectResponse == COCONNECT_OK){
ConnectResponse = ConnObjectIter->second->Connect(true);
if (ConnectResponse == COCONNECT_OK){
ExitLoop = true;
break;
} else {
ExitLoop = true;
iter->second = 2;
break;
}
ExitLoop = true;
break;
} else {
ExitLoop = true;
iter->second = 2;
break;
}
}
#if defined(__APPLE__)
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
#elif defined(__WIN32__)
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
#else
frmMainPtrGet->UpdateSSLAccountStatus(AccountID, 0, ConnObjectIter->second->BuildSSLCollection());
#endif
if (iter->second == 2 || iter->second == 3 || iter->second == 4){
break;
}
// Look in directory and see which vCards to add and delete
// In short:
// vCard exists but not in ETagDB - Add (and upload).
// vCard missing but in ETagDB - Delete (from server).
// Start by looking for vCards that are not in the ETagDB.
wxDir AccDir(AccountDirFinal);
wxString AccDirFilename;
bool ContinueProcess = AccDir.GetFirst(&AccDirFilename, wxEmptyString, wxDIR_DEFAULT);
COContactList ServerContactList2 = ConnObjectIter->second->GetContactList(SyncTokenLoad.ToStdString());
// Process the server data.
for (std::vector::iterator ContactInfo = ServerContactList2.ListData.begin();
ContactInfo != ServerContactList2.ListData.end(); ContactInfo++){
if (ContactInfo->Status == COCS_UPDATED){
vCardDownloadDataFileClass vCardNewData;
vCardNewData.DataType = 0;
vCardDownloadData.insert(std::make_pair(ContactInfo->Location, vCardNewData));
} else if (ContactInfo->Status == COCS_DELETED){
vCardDelete.Add(ContactInfo->Location, 1);
}
}
// Look for vCards that are missing but in the ETagDB.
for (std::map::iterator etagiter = ETagDBData.begin();
etagiter != ETagDBData.end(); etagiter++){
// Check if the vCard exists.
if (!wxFileExists(AccountDirFinal + etagiter->first)){
// vCard doesn't exist so mark for deleting.
vCardDelete.Add(etagiter->first, 1);
}
}
// Compare Server with the ETag DB. Work out which
// needs to updated remotely and which needs to be
// updated locally.
for (std::vector::iterator ContactInfo = ServerContactList2.ListData.begin();
ContactInfo != ServerContactList2.ListData.end(); ContactInfo++){
if (ETagDBData.find(ContactInfo->Location) == ETagDBData.end()){
continue;
}
std::map::iterator lociter = ETagDBData.find(ContactInfo->Location);
ETagData etd = lociter->second;
wxString ETagSrv = ContactInfo->Data;
// Check if the local ETag value has 'DELETED' set and skip
// checking this file if it does.
if (etd.ETagValue == "DELETED"){
continue;
}
// Compare local ETag with original local ETag.
// If different, update to server is required.
if (etd.ETagValue != etd.ETagOrigValue){
// Check if local original ETag is different from server ETag.
// If it is then throw up a conflict resolution dialog.
if (etd.ETagOrigValue != ETagSrv){
vCard34Conv vCard34Obj;
wxString FullFilename;
vCard ClientData;
vCard ConvertedV4Data;
std::string ServerContactDataString;
wxString ServerContactData;
// Conflict. Bring up conflict resolution dialog.
// Get the server contact data for comparison.
ConnObjectIter->second->GetContact(ContactInfo->Location, &ServerContactDataString);
ServerContactData = wxString::FromUTF8(ServerContactDataString.c_str());
FullFilename = CreateFilenamePath(AccountDirFinal, ContactInfo->Location);
// Convert it to v4.
vCard34Obj.ConvertToV4(&ServerContactData, &ConvertedV4Data);
vCardConflictObj vCardProcData;
vCardProcData.vCardLocalData = &ClientData;
vCardProcData.vCardServerData = &ConvertedV4Data;
// Load the client data from the filename given.
ClientData.LoadFile(FullFilename);
// Show dialog.
bool *PauseMode = new bool;
int ConflictResult;
QRNotif qrn;
frmMain *frmMainPtrGet = static_cast(frmMainPtr);
*PauseMode = TRUE;
qrn.QResponse = &ConflictResult;
qrn.PausePtr = PauseMode;
vCardProcData.QRNotifData = &qrn;
wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
event.SetClientData(&vCardProcData);
wxPostEvent(frmMainPtrGet, event);
while (*PauseMode == TRUE){
//nanosleep(&n1, &n2);
SleepFor(250000000);
}
delete PauseMode;
PauseMode = NULL;
// If replacing local version, store copy for now.
// Otherwise upload to server.
if (ConflictResult == 0){
// Decide Later.
continue;
} else if (ConflictResult == 1){
// Decided to use client version.
vCardUpdateLocal.Remove(ContactInfo->Location);
vCardUpdateRemote.Add(ContactInfo->Location, 1);
} else if (ConflictResult == 2){
// Decided to use server version.
// Store the converted downloaded copy for
// processing later.
//vCardUpdateLocal.Add(srviter->first, 1);
vCardDownloadDataFileClass vCardNewData;
vCardNewData.DataType = 1;
vCardNewData.FileData = ConvertedV4Data.WriteString();
ConvertedV4Data.WriteFile(FullFilename);
vCardDownloadData.insert(std::make_pair(ContactInfo->Location, vCardNewData));
}
} else {
// Send vCard to the server.
vCardUpdateRemote.Add(ContactInfo->Location, 1);
}
} else {
// Check if local ETag is different from server ETag.
// If different, obtain the vCard from the server.
if (etd.ETagOrigValue != ETagSrv){
vCardUpdateLocal.Add(ContactInfo->Location, 1);
}
}
}
// Process the vCards that need to be downloaded and added/overwritten.
wxString vCardFilenameFinal;
wxString vCardOutputData;
wxString vCardInputData;
wxString ETagFileData;
wxFFile vCardFile;
for (std::map::iterator additer = vCardDownloadData.begin();
additer != vCardDownloadData.end(); additer++){
vCardFilenameFinal.Clear();
vCardInputData.Clear();
vCardOutputData.Clear();
ETagFileData.Clear();
vCardFilenameFinal = CreateFilenamePath(AccountDirFinal, additer->first);
ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
if (additer->second.DataType == 0){
vCard ConvertedV4Data;
// Grab the file from the server and write the contact out.
vCard34Conv vCard34Obj;
wxString ServerContactData;
std::string ServerContactDataString;
// Conflict. Bring up conflict resolution dialog.
// Get the server contact data for comparison.
ConnObjectIter->second->GetContact(additer->first.ToStdString(), &ServerContactDataString);
vCardInputData = wxString::FromUTF8(ServerContactDataString.c_str());
vCard34Obj.ConvertToV4(&vCardInputData, &ConvertedV4Data);
ConvertedV4Data.WriteFile(vCardFilenameFinal);
// Get the server ETag.
wxString ServerETag;
COServerResponse ServerEntityTag = ConnObjectIter->second->GetServerEntityTagValue(additer->first.ToStdString());
if (ServerEntityTag.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
ServerETag = wxString::FromUTF8(ServerEntityTag.EntityTag.c_str());
// Add to the ETag Database.
ETagDBPtr->AddETag(additer->first, ServerETag, ServerETag);
} else if (additer->second.DataType == 1){
// Write out the contact to the account directory.
vCardFilenameFinal = CreateFilenamePath(AccountDirFinal, additer->first);
vCardOutputData = additer->second.FileData;
vCardFile.Open(vCardFilenameFinal, wxT("w"));
if (vCardFile.IsOpened()){
vCardFile.Write(vCardOutputData, wxConvAuto());
vCardFile.Close();
}
// Update the ETagDB.
wxString ServerETag;
COServerResponse ServerEntityTag = ConnObjectIter->second->GetServerEntityTagValue(additer->first.ToStdString());
if (ServerEntityTag.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
ServerETag = wxString::FromUTF8(ServerEntityTag.EntityTag.c_str());
// Add to the ETag Database.
ETagDBPtr->AddETag(additer->first, ServerETag, ServerETag);
}
}
// Check if any errors occured before continuing.
if (iter->second != 1){
break;
}
// Look for vCard files which aren't in the ETagDB.
while(ContinueProcess){
// Check and make sure that the filename ends in .vcf/.vcard
// Skip any file that beings with a dot.
if (AccDirFilename.Left(1) == wxT(".")){
ContinueProcess = AccDir.GetNext(&AccDirFilename);
continue;
}
if (AccDirFilename.Right(4) != wxT(".vcf") &&
AccDirFilename.Right(6) != wxT(".vcard")){
ContinueProcess = AccDir.GetNext(&AccDirFilename);
continue;
}
// Look in the ETagDB for the file.
bool ETagExists = ETagDBPtr->CheckETagExists(AccDirFilename);
if (ETagExists == FALSE){
// Add the vCard to the list to be added.
vCardAdd.Add(AccDirFilename, 1);
}
ContinueProcess = AccDir.GetNext(&AccDirFilename);
}
// Process the vCards to add/update to the server.
for (int vi = 0; vi < vCardAdd.GetCount(); vi++){
ETagDB *ETagDBPtr = ETagTmrPtr->GetPointer(AccountDir);
ETag = ETagDBPtr->GetETag(vCardAdd[vi]);
ETagOriginal = ETagDBPtr->GetETagOriginal(vCardAdd[vi]);
ContactFilename = vCardAdd[vi];
FullFilename = CreateFilenamePath(AccountDirFinal, vCardAdd[vi]);
ContactFilename.Trim();
if (ETag == ETagOriginal && ETagDBPtr->ETagExists(vCardAdd[vi])){
// Compare the ETag with the Server ETag.
COServerResponse ServerEntityTag = ConnObjectIter->second->GetServerEntityTagValue(vCardAdd[vi].ToStdString());
if (ServerEntityTag.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
ETagServer = wxString::FromUTF8(ServerEntityTag.EntityTag.c_str());
if (ETagOriginal != ETagServer){
// Server ETag is different from original ETag.
// This is a conflict which the user will now
// need to resolve.
frmMain *frmMainPtrGet = static_cast(frmMainPtr);
vCard34Conv vCard34Obj;
wxString ServerContactData;
std::string ServerContactDataString;
vCard ClientData;
vCard ConvertedV4Data;
// Load the client data from the filename given.
COServerResponse GetContactResponse = ConnObjectIter->second->GetContact(vCardAdd[vi].ToStdString(), &ServerContactDataString);
if (GetContactResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
ServerContactData = wxString::FromUTF8(ServerContactDataString.c_str());
// Process v3 version into v4 version.
vCard34Obj.ConvertToV4(&ServerContactData, &ConvertedV4Data);
vCardConflictObj vCardProcData;
vCardProcData.vCardLocalData = &ClientData;
vCardProcData.vCardServerData = &ConvertedV4Data;
ClientData.LoadFile(FullFilename);
// Setup Conflict Resolution Dialog.
// Fetch Data from Server and convert.
bool *PauseMode = new bool;
int ConflictResult;
QRNotif qrn;
*PauseMode = TRUE;
qrn.QResponse = &ConflictResult;
qrn.PausePtr = PauseMode;
vCardProcData.QRNotifData = &qrn;
wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
event.SetClientData(&vCardProcData);
wxPostEvent(frmMainPtrGet, event);
while (*PauseMode == TRUE){
//nanosleep(&n1, &n2);
SleepFor(250000000);
}
delete PauseMode;
PauseMode = NULL;
if (ConflictResult == 0){
// Decide Later.
iter->second = 4;
continue;
} else if (ConflictResult == 1){
// Decided to use client version.
COServerResponse EditContactResponse = ConnObjectIter->second->EditContact(vCardAdd[vi].ToStdString(), std::string(ClientData.WriteString().ToUTF8()));
if (EditContactResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
iter->second = 4;
} else if (ConflictResult == 2){
// Decided to use server version.
// Download server version.
ConvertedV4Data.WriteFile(CreateFilenamePath(AccountDirFinal, vCardAdd[vi]));
iter->second = 4;
}
} else {
// Setup the filename for the contact being added.
wxString wxSFilename = CreateFilenamePath(AccountDirFinal, vCardAdd[vi]);
wxString wxSCardData;
wxString TaskData;
// Load the data from the file.
wxFFile wxFCard;
wxFCard.Open(wxSFilename, wxT("r"));
if (wxFCard.IsOpened()){
wxFCard.ReadAll(&wxSCardData, wxConvAuto());
wxFCard.Close();
}
// Convert the data to v3.
vCard34Conv vCard34Obj;
vCard34Obj.ConvertToV3(wxSFilename, &TaskData);
// Upload the data to the server.
COServerResponse AddContactResponse = ConnObjectIter->second->AddContact(vCardAdd[vi].ToStdString(), std::string(TaskData.ToUTF8()));
if (AddContactResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
// Get the Server ETag and put it in the ETag database.
COServerResponse EntityTagResponse = ConnObjectIter->second->GetServerEntityTagValue(vCardAdd[vi].ToStdString());
if (EntityTagResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
ETagServer = wxString::FromUTF8(EntityTagResponse.EntityTag.c_str());
ETagDBPtr->AddETag(vCardAdd[vi], ETagServer, ETagServer);
}
} else {
if (ETagOriginal != ETagServer){
// Server ETag is different from original ETag.
// This is a conflict which the user will now
// need to resolve.
frmMain *frmMainPtrGet = (frmMain *)frmMainPtr;
vCard34Conv vCard34Obj;
std::string ServerContactDataString;
wxString ServerContactData;
vCard ClientData;
vCard ConvertedV4Data;
// Load the client data from the filename given.
COServerResponse GetContactResponse = ConnObjectIter->second->GetContact(vCardAdd[vi].ToStdString(), &ServerContactDataString);
if (GetContactResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
ServerContactData = wxString::FromUTF8(ServerContactDataString.c_str());
ClientData.LoadFile(FullFilename);
// Process v3 version into v4 version.
vCard34Obj.ConvertToV4(&ServerContactData, &ConvertedV4Data);
vCardConflictObj vCardProcData;
vCardProcData.vCardLocalData = &ClientData;
vCardProcData.vCardServerData = &ConvertedV4Data;
bool *PauseMode = new bool;
int ConflictResult;
QRNotif qrn;
*PauseMode = TRUE;
qrn.QResponse = &ConflictResult;
qrn.PausePtr = PauseMode;
vCardProcData.QRNotifData = &qrn;
wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
event.SetClientData(&vCardProcData);
wxPostEvent(frmMainPtrGet, event);
while (*PauseMode == TRUE){
SleepFor(250000000);
}
delete PauseMode;
PauseMode = NULL;
if (ConflictResult == 0){
// Decide Later.
iter->second = 4;
continue;
} else if (ConflictResult == 1){
// Decided to use client version.
COServerResponse EditContactResponse = ConnObjectIter->second->EditContact(vCardAdd[vi].ToStdString(), std::string(ClientData.WriteString().ToUTF8()));
if (EditContactResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
iter->second = 4;
} else if (ConflictResult == 2){
// Decided to use server version.
// Write server version to file.
ConvertedV4Data.WriteFile(CreateFilenamePath(AccountDirFinal, vCardAdd[vi]));
iter->second = 4;
}
} else {
// Setup the filename for the contact being added.
wxString wxSFilename = CreateFilenamePath(AccountDirFinal, vCardAdd[vi]);
wxString wxSCardData;
wxString TaskData;
// Load the data from the file.
wxFFile wxFCard;
wxFCard.Open(wxSFilename, wxT("r"));
if (wxFCard.IsOpened()){
wxFCard.ReadAll(&wxSCardData, wxConvAuto());
wxFCard.Close();
}
// Convert the data to v3.
vCard34Conv vCard34Obj;
vCard34Obj.ConvertToV3(wxSFilename, &TaskData);
// Upload the data to the server.
COServerResponse AddContactResponse = ConnObjectIter->second->AddContact(vCardAdd[vi].ToStdString(), std::string(TaskData.ToUTF8()));
if (AddContactResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
// Get the Server ETag and put it in the ETag database.
COServerResponse EntityTagResponse = ConnObjectIter->second->GetServerEntityTagValue(vCardAdd[vi].ToStdString());
if (EntityTagResponse.RequestResult != COREQUEST_OK){
iter->second = 2;
break;
}
ETagDBPtr->AddETag(vCardAdd[vi], ETagServer, ETagServer);
}
}
}
if (iter->second != 1){
break;
}
// Process the vCards to delete locally.
for (int vi = 0; vi < vCardDelete.GetCount(); vi++){
if (!wxRemoveFile(CreateFilenamePath(AccountDirFinal, vCardDelete[vi]))){
} else {
ETagDBPtr->RemoveETag(vCardDelete[vi]);
}
}
// Process the vCards to delete from the server.
std::map *ETagFilenameMap = ETagDBPtr->GetFilenamePointer();
std::list DeleteList;
for (std::map::iterator deliter = ETagFilenameMap->begin();
deliter != ETagFilenameMap->end(); deliter++){
// Look through the ETagDB and find contacts which are marked as DELETED.
if (deliter->second == wxT("DELETED")){
ConnObjectIter->second->DeleteContact(deliter->first.ToStdString());
// Delete the ETag as the file has now been deleted.
DeleteList.push_back(deliter->first);
}
}
for (std::list::iterator removeetagiter = DeleteList.begin();
removeetagiter != DeleteList.end(); removeetagiter++){
ETagDBPtr->RemoveETag(*removeetagiter);
}
// Write out the update server sync token.
wxString ServerSyncToken = wxString::FromUTF8(ServerContactList2.SyncToken.c_str());
ServerSyncToken.Trim();
if (!ServerSyncToken.IsEmpty()){
wxFFile SyncWrite;
SyncWrite.Open(AccountSyncTokenFilename, wxT("w"));
if (SyncWrite.IsOpened()){
SyncWrite.Write(ServerSyncToken, wxConvAuto());
SyncWrite.Close();
}
}
// Check for another sync token. If there is another
// sync token then repeat this. If token matches then stop processing.
if (SyncTokenLoad == ServerSyncToken){
KeepUpdating = FALSE;
}
}
// Mark as completed.
wxString AccountNameFinal;
AccountNameFinal = PrefData.accounts.GetAccountDirectory(AccountID);
AccountNameFinal.Append(wxT(".carddav"));
wxCommandEvent reloadevent(RELOADCONTACTLIST);
reloadevent.SetString(AccountNameFinal);
wxPostEvent(this->GetParent(), reloadevent);
iter->second = 4;
continue;
} else {
// Update the data to the server.
iter->second = 4;
continue;
}
while (iter->second == 1){
SleepFor(125000000);
}
break;
}
}
if (TasksFoundProc == FALSE){
TasksActive = FALSE;
ProcessTasksData = FALSE;
} else {
wxCommandEvent eventp(ACTMGR_STARTTIMER);
wxPostEvent(this, eventp);
}
wxCommandEvent event(ACTMGR_STARTPROCESSTIMER);
wxPostEvent(this, event);
}
void frmActivityMgr::ProcessTasks()
{
std::thread ProcessThread(&frmActivityMgr::ProcessTasksThread, this);
ProcessThread.detach();
}
void frmActivityMgr::SetupPointers(wxETagProcessTimer *ETagTmrPtrInc, void *frmMainPtrInc)
{
ETagTmrPtr = ETagTmrPtrInc;
frmMainPtr = frmMainPtrInc;
}
void frmActivityMgr::ResumeProcessing(wxCommandEvent &event){
QRNotif *qrn = (QRNotif *)event.GetClientData();
int *QRes = qrn->QResponse;
*qrn->PausePtr = FALSE;
*QRes = event.GetInt();
}
void frmActivityMgr::ToggleConnectionStatus( wxCommandEvent &event ){
wxCommandEvent connevent(CONNSTAT_UPDATE);
if (ApplicationSleepMode == FALSE){
connevent.SetInt(1);
ApplicationSleepMode = TRUE;
mnuSleepMode->Check(true);
} else {
connevent.SetInt(0);
ApplicationSleepMode = FALSE;
mnuSleepMode->Check(false);
wxCommandEvent event(ACTMGR_STARTTIMER);
wxPostEvent(this, event);
wxCommandEvent eventp(ACTMGR_STARTPROCESSTIMER);
wxPostEvent(this, eventp);
}
wxPostEvent(GetParent(), connevent);
}
void frmActivityMgr::SleepMode( wxCommandEvent &event ){
wxCommandEvent connevent(ACTMGR_TOGGLECONN);
wxPostEvent(this, connevent);
}
void frmActivityMgr::WriteServerCertificate(wxString AccountName, SSLCertCollection SSLCertInc){
wxString ServerCertFinal;
// Get the Cert section of the certificate and write it to the file.
ServerCertFinal = GetAccountDir(AccountName, TRUE);
wxFile CertFile;
std::map::iterator SSLCDIter = SSLCertInc.SSLCollection.find(0);
std::multimap::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
CertFile.Open(ServerCertFinal, wxFile::write);
CertFile.Write(SSLDataIter->second, wxConvUTF8);
CertFile.Close();
}
void frmActivityMgr::WriteServerCertificate(wxString AccountName, SSLCertCollectionString SSLCertInc){
wxString ServerCertFinal;
// Get the Cert section of the certificate and write it to the file.
ServerCertFinal = GetAccountDir(AccountName, TRUE);
wxFile CertFile;
std::map::iterator SSLCDIter = SSLCertInc.SSLCollection.find(0);
std::multimap::iterator SSLDataIter = SSLCDIter->second.CertData.find("Cert");
CertFile.Open(ServerCertFinal, wxFile::write);
CertFile.Write(SSLDataIter->second, wxConvUTF8);
CertFile.Close();
}
void frmActivityMgr::StartTimer(wxCommandEvent& event){
ActListProcTimer.Start(1000, FALSE);
}
void frmActivityMgr::StopTimer(wxCommandEvent& event){
ActListProcTimer.Stop();
}
void frmActivityMgr::StartProcessTimer(wxCommandEvent& event){
ActProcessTimer.Start(1000, FALSE);
}
void frmActivityMgr::StopProcessTimer(wxCommandEvent& event){
ActProcessTimer.Stop();
}
void frmActivityMgr::StartAnimationTimer(wxCommandEvent& event){
AnimationTimer.StartAnimation();
}
void frmActivityMgr::UpdateStatusLabel(wxCommandEvent& event){
ActivityMgrLabelUpdate *actmgrudata = (ActivityMgrLabelUpdate*)event.GetClientData();
if (actmgrudata != NULL){
lstActivity->SetItem(actmgrudata->ItemIndex, 2, actmgrudata->ItemLabel);
delete actmgrudata;
actmgrudata = NULL;
}
}