// 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; } }