Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Split carddav/carddav.cpp down into 8 files to make it manageable.
authorSteve Brokenshire <sbrokenshire@xestia.co.uk>
Tue, 20 Oct 2015 18:34:42 +0000 (19:34 +0100)
committerSteve Brokenshire <sbrokenshire@xestia.co.uk>
Tue, 20 Oct 2015 18:34:42 +0000 (19:34 +0100)
source/carddav/carddav-connect.cpp [new file with mode: 0644]
source/carddav/carddav-contactlist.cpp [new file with mode: 0644]
source/carddav/carddav-defaultadrurl.cpp [new file with mode: 0644]
source/carddav/carddav-processdata.cpp [new file with mode: 0644]
source/carddav/carddav-servercontact.cpp [new file with mode: 0644]
source/carddav/carddav-serveretag.cpp [new file with mode: 0644]
source/carddav/carddav-sslverify.cpp [new file with mode: 0644]
source/carddav/carddav.cpp
source/carddav/carddav.h

diff --git a/source/carddav/carddav-connect.cpp b/source/carddav/carddav-connect.cpp
new file mode 100644 (file)
index 0000000..d759cde
--- /dev/null
@@ -0,0 +1,273 @@
+#include "carddav.h"
+#include "../version.h"
+#include <wx/wx.h>
+#include <wx/tokenzr.h>
+#include <wx/ffile.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <map>
+#include <thread>
+#include "../vcard/vcard.h"
+#include "../common/dirs.h"
+
+bool CardDAV::Connect(){
+
+       PageData.Clear();
+       PageHeader.Clear();
+
+       SSLStatus = TRUE;
+       AuthPassed = TRUE;
+       AbortConnection = FALSE;
+
+       CURL *conn;
+       CURLcode conncode;
+       wxString ServerAddressURL;
+       wxString ServerAuth;
+       wxString ServerAddressSSL;
+       wxString ServerAddressNormal;   
+
+        conn = curl_easy_init();
+
+       struct CardDAVCURLPasser {
+       
+               CardDAV *Data;
+               bool HeaderMode = TRUE;
+       
+       } CardDAVHeader, CardDAVFooter;
+
+       CardDAVHeader.Data = this;
+       CardDAVHeader.HeaderMode = TRUE;
+       
+       CardDAVFooter.Data = this;
+       CardDAVFooter.HeaderMode = FALSE;
+
+       wxString Data1;
+       wxString Data2;
+       
+       ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
+       ServerAddressSSL = wxT("https://") + ServerAddressURL;
+       ServerAddressNormal = wxT("http://") + ServerAddressURL;
+       
+       ServerAuth = ServerUser + wxT(":") + ServerPass;
+       
+       // Try SSL first.
+
+
+       /*
+       char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];
+       //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());
+       strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));
+       
+       char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];
+       //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       
+       strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));
+
+       char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];
+       //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); 
+       strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));
+       
+       */
+       
+       if (ServerSSL){
+
+               union {
+                       struct curl_slist       *certdata;
+                       struct curl_certinfo    *certinfo;
+               } ptr;
+
+               ptr.certdata = NULL;
+
+               // Setup two initial connections and attempt to get the certificate data.
+
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
+
+               conncode = (curl_easy_perform(conn));
+
+               // Check if the SSL certificate is valid or self-signed or some other
+               // error occured.
+
+               if (conncode == CURLE_OK){
+
+                       // Connection is OK. Do nothing.
+
+               } else if (conncode == CURLE_SSL_CACERT){
+
+                       // Post message saying SSL certificate is invalid. 
+
+                       curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata);
+
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                               curl_easy_strerror(conncode));
+
+                       ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));
+
+                       *ServerResult = FALSE;
+                       return FALSE;
+
+               }
+
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
+               
+               if (AllowSelfSign == TRUE){
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L);
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L);
+               }
+
+               conncode = (curl_easy_perform(conn));
+               
+               ptr.certdata = NULL;
+
+               curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata);
+               
+               if (conncode == CURLE_OK){
+
+                       // Process the server header response and look for
+                       // 'addressbook' within the DAV header.
+
+                       wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n"));
+                       wxString wxSHeaderLine;
+                       std::map<int, wxString> DAVHeaderLines;
+
+                       while (wxSHeaderLines.HasMoreTokens()){
+
+                               wxSHeaderLine = wxSHeaderLines.GetNextToken();
+
+                               if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){
+
+                                       // Look for address book in the line.
+
+                                       if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){
+
+                                               HasCalDAVSupport = TRUE;
+
+                                       }
+
+                               }
+
+                       }
+
+                       *ServerResult = TRUE;
+                       ValidResponse = TRUE;
+                       AuthPassed = TRUE;
+                       SSLStatus = TRUE;
+                       return TRUE;
+
+               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
+               
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+                               
+                       ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));
+
+                       *ServerResult = TRUE;
+                       ValidResponse = FALSE;
+                       AuthPassed = FALSE;
+                       SSLStatus = TRUE;
+                       return TRUE;
+               
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+
+                       ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));
+
+                       *ServerResult = FALSE;
+                       return FALSE;                                   
+
+               }
+
+       } else {
+       
+       // No SSL.
+               
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);    
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+
+               conncode = (curl_easy_perform(conn));
+
+               if (conncode == CURLE_OK){
+
+                       // Process the server header response and look for
+                       // 'addressbook' within the DAV header.
+                       
+                       wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n"));
+                       wxString wxSHeaderLine;
+                       std::map<int, wxString> DAVHeaderLines;
+                       
+                       while (wxSHeaderLines.HasMoreTokens()){
+                       
+                               wxSHeaderLine = wxSHeaderLines.GetNextToken();
+                               
+                               if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){
+                               
+                                       // Look for address book in the line.
+                                       
+                                       if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){
+                                       
+                                               HasCalDAVSupport = TRUE;
+                                       
+                                       }
+                               
+                               }
+                       
+                       }
+
+                       *ServerResult = TRUE;
+                       ValidResponse = TRUE;                   
+                       AuthPassed = TRUE;
+                       SSLStatus = FALSE;
+                       return TRUE;
+
+               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
+               
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+                                       
+                       *ServerResult = TRUE;
+                       ValidResponse = FALSE;
+                       AuthPassed = FALSE;
+                       SSLStatus = FALSE;
+                       return TRUE;
+               
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+                               
+                       *ServerResult = FALSE;
+                       return FALSE;
+
+               }
+               
+               // TODO: Double check and make sure HTTP Authentication is possible.
+               
+       }               
+               
+       *ServerResult = TRUE;
+       return TRUE;    
+
+}
diff --git a/source/carddav/carddav-contactlist.cpp b/source/carddav/carddav-contactlist.cpp
new file mode 100644 (file)
index 0000000..188e772
--- /dev/null
@@ -0,0 +1,929 @@
+#include "carddav.h"
+#include "../version.h"
+#include <wx/wx.h>
+#include <wx/tokenzr.h>
+#include <wx/ffile.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <map>
+#include <thread>
+#include "../vcard/vcard.h"
+#include "../common/dirs.h"
+
+ContactListData CardDAV::GetContactList(wxString SyncTokenInc){
+
+       ContactListData ContactListFinal;
+       std::map<wxString,FileSyncData> ContactList;
+       
+       PageData.Clear();
+       PageHeader.Clear();
+
+       SSLStatus = TRUE;
+       AuthPassed = TRUE;
+       AbortConnection = FALSE;
+
+       CURL *conn;
+       wxString ServerAddressURL;
+       wxString ServerAuth;
+       wxString ServerAddressSSL;
+       wxString ServerAddressNormal;
+
+       conn = curl_easy_init();
+       
+       struct CardDAVCURLPasser {
+       
+               CardDAV *Data;
+               bool HeaderMode = TRUE;
+       
+       } CardDAVHeader, CardDAVFooter;
+
+       CardDAVHeader.Data = this;
+       CardDAVHeader.HeaderMode = TRUE;
+       
+       CardDAVFooter.Data = this;
+       CardDAVFooter.HeaderMode = FALSE;
+
+       wxString Data1;
+       wxString Data2;
+       
+       ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + wxT("/");
+       ServerAddressSSL = wxT("https://") + ServerAddressURL;
+       ServerAddressNormal = wxT("http://") + ServerAddressURL;
+       
+       ServerAuth = ServerUser + wxT(":") + ServerPass;
+       
+       // Load the sync token file (if it exists).
+       
+       wxCharBuffer SyncDataBuffer;
+       wxString SyncData;
+       
+       SyncData.Clear();
+       
+       SyncTokenInc.Trim();
+       
+       if (!SyncTokenInc.IsEmpty()){
+               
+               SyncData = wxT("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
+               SyncData.Append(wxT("<D:sync-collection xmlns:D=\"DAV:\"\n"));
+               SyncData.Append(wxT(" xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"));
+               SyncData.Append(wxT("<D:sync-token>"));
+               //SyncData.Trim();
+               //SyncData.Append(wxT("data:,00378c55-1f44-44a2-a255-84f6560b5cac_580"));
+               SyncData.Append(SyncTokenInc);
+               //SyncData.Trim();
+               SyncData.Append(wxT("</D:sync-token>\n"));
+               SyncData.Append(wxT("<D:sync-level>1</D:sync-level>\n"));
+               SyncData.Append(wxT("<D:prop>\n"));
+               SyncData.Append(wxT("   <D:getetag/>\n"));
+               SyncData.Append(wxT("</D:prop>\n"));
+               SyncData.Append(wxT("</D:sync-collection>"));
+               
+               SyncDataBuffer = SyncData.ToUTF8();
+       
+       } else {
+               
+               SyncData = wxT("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+               SyncData.Append(wxT("<D:sync-collection xmlns:D=\"DAV:\""));
+               SyncData.Append(wxT(" xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"));
+               SyncData.Append(wxT("<D:sync-token/>\n"));
+               SyncData.Append(wxT("<D:sync-level>1</D:sync-level>\n"));
+               SyncData.Append(wxT("<D:prop>\n"));
+               SyncData.Append(wxT("   <D:getetag/>\n"));
+               SyncData.Append(wxT("</D:prop>\n"));
+               SyncData.Append(wxT("</D:sync-collection>\n"));
+               
+               SyncDataBuffer = SyncData.ToUTF8();
+
+       }
+       
+       //static const char* query = SyncData.mb_str();
+       
+       /*char *query = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\
+               <D:sync-collection xmlns:D=\"DAV:\"\n\
+                xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n\
+               <D:sync-token>data:,00378c55-1f44-44a2-a255-84f6560b5cac_580</D:sync-token>\n\
+               <D:sync-level>1</D:sync-level>\n\
+               <D:prop>\n\
+                       <D:getetag/>\n\
+               </D:prop>\n\
+       </D:sync-collection>\n";*/
+       const char* query = SyncDataBuffer.data();
+       
+       // Try SSL first.
+
+       std::map<int,int>::iterator ActIter;
+       struct UploadDataStruc UploadData;
+       
+       ActIter = ActivityListPtr->find((int)ItemIndex);
+
+       curl_slist *slist = NULL;       
+
+       slist = curl_slist_append(slist, "Depth: 1");
+
+       if (ServerSSL){
+
+               wxString ServerCertFilename;
+               bool MatchingCert = FALSE;
+
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
+               curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
+
+               ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
+
+               if (wxFile::Exists(ServerCertFilename) == TRUE){
+               
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
+                       curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
+               
+               }
+
+               //UploadData.readptr = &CardDAVDataQuery;
+               //UploadData.sizeleft = CardDAVDataQuery.Len();
+               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
+               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
+               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
+               
+               //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
+
+               claconncode = (curl_easy_perform(conn));
+
+               // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without
+               // the local certificate in use.
+
+               if (claconncode == CURLE_PEER_FAILED_VERIFICATION){
+                       
+                       curl_easy_cleanup(conn);
+                       conn = curl_easy_init();
+                       
+                       curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+                       curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+                       curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
+                       curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+                       curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+                       curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+                       curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+                       curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                       curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+                       curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+                       curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+                       curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+                       curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
+                       curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+                       curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
+                       curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
+                       curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
+                       curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
+                       
+                       claconncode = (curl_easy_perform(conn));
+                       
+                       // If claconncode is CURLE_OK then delete the certificate file as that
+                       // is no longer needed.
+                       
+                       if (claconncode == CURLE_OK){
+                       
+                               // Delete the certificate file.
+                               
+                               wxRemoveFile(ServerCertFilename);
+                       
+                       }
+               
+               }
+
+               // Check if it fails with a CURLE_SSL_CACERT then compare
+               // the certificates as PEM files.
+               
+               if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
+               
+                       //curl_easy_cleanup(conn);
+                       //conn = curl_easy_init();
+
+                       CURL *sslerrconn;
+                       sslerrconn = curl_easy_init();
+                       CURLcode sslerrconncode;
+
+                       //claconncode = (curl_easy_perform(conn));
+
+                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
+
+                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
+                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
+                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
+                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
+                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
+                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
+               
+                       wxString SSLLocalData;
+                       wxString SSLServerData;
+               
+                       sslerrconncode = (curl_easy_perform(sslerrconn));
+               
+                       SSLCertCol = BuildSSLCollection(sslerrconn);
+                       std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);
+                       std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
+                       
+                       wxFFile SSLLocalFile;
+                       
+#if wxABI_VERSION < 20900
+                       SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
+#else
+                       SSLLocalFile.Open(ServerCertFilename, wxT("r"));
+#endif 
+       
+                       // Load the recovery database for tasks not done.
+       
+                       if (SSLLocalFile.IsOpened() == TRUE){
+
+                       // Check if we are using wxWidgets version 2.8 or less and
+                       // execute the required command accordingly.
+       
+                               SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
+               
+       
+                       }
+                       
+                       SSLServerData = SSLDataIter->second;
+                       
+                       if (SSLLocalData == SSLServerData){
+                       
+                               // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
+                               // and CURLOPT_SSL_VERIFYHOST off.
+                       
+                               curl_easy_cleanup(conn);
+                               conn = curl_easy_init();
+                               
+                               PageHeader.clear();
+                               PageData.clear();
+                               
+                               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+                               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+                               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+                               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+                               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+                               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+                               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+                               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+                               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+                               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+                               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
+                               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+                               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
+                               curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
+                               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
+                               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
+                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);
+                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);
+                       
+                               claconncode = (curl_easy_perform(conn));
+                               
+                               MatchingCert = TRUE;
+                       
+                       }
+                       
+                       if (MatchingCert == FALSE){
+               
+                               claconncode = CURLE_SSL_CACERT;
+                               return ContactListFinal;
+               
+                       }
+                       
+                       curl_easy_cleanup(sslerrconn);
+               
+               }
+
+               // Sort out SSL error.
+               
+               // When SSL cert error occurs, connect again and fetch certificates.
+               // Display a message to the user explaining that an invalid
+               // certificate has been given and let the user decide what
+               // to do next.
+
+               if (claconncode == CURLE_OK){
+
+               } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
+               
+                       CURL *sslerrconn;
+                       sslerrconn = curl_easy_init();
+                       CURLcode sslerrconncode;
+               
+                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
+               
+                       // Replace conn with sslerrconn!
+               
+                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
+                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
+                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
+                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
+                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
+                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
+               
+                       sslerrconncode = (curl_easy_perform(sslerrconn));
+
+                       SSLCertCol = BuildSSLCollection(sslerrconn);
+                       SSLCertCol.SuccessCode = 1;
+
+                       return ContactListFinal;
+               
+               } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
+               
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(claconncode));
+                       int http_code = 0;
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
+                       fprintf(stderr, "Error code was: %d\n", http_code);
+                                       
+                       return ContactListFinal;
+               
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(claconncode));
+                       int http_code = 0;
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
+                       fprintf(stderr, "Error code was: %d\n", http_code);
+
+                       return ContactListFinal;
+
+               }
+
+               SSLCertCol = BuildSSLCollection(conn);
+
+       } else {
+       
+       // No SSL.
+               
+               wxString EmptyString;
+               
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
+
+               //UploadData.readptr = &CardDAVDataQuery;
+               //UploadData.sizeleft = CardDAVDataQuery.Len();
+               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
+               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
+               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
+               
+               //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));           
+               
+               PageData.Clear();
+               PageHeader.Clear();
+               
+               claconncode = (curl_easy_perform(conn));
+
+               if (claconncode == CURLE_OK){
+
+
+
+               } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
+               
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(claconncode));
+                       int http_code = 0;
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
+                       fprintf(stderr, "Error code was: %i\n", http_code);
+                                       
+                       return ContactListFinal;
+                       
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(claconncode));
+                       int http_code = 0;
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
+                       fprintf(stderr, "Error code was: %i\n", http_code);
+                               
+                       return ContactListFinal;
+
+               }
+               
+       }
+
+       xmlDocPtr xmlCardDAVDoc;
+       xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);
+
+       xmlNodePtr nodeLevel1;
+       xmlNodePtr nodeLevel2;
+       xmlNodePtr nodeLevel3;
+       xmlNodePtr nodeLevel4;
+       xmlNodePtr nodeLevel5;
+       xmlNodePtr nodeLevel6;
+       
+       xmlNodePtr nodeStatusLv1;
+       xmlNodePtr nodeStatusLv2;
+
+       std::map<wxString,wxString> xmlDataMap;
+       std::map<wxString,wxString> ServerETagData;
+
+       wxString DataFilename;
+       wxString DataSyncToken;
+       int DataFileStatus;
+       wxString ETagData;
+       bool SyncTokenFound = FALSE;
+
+       std::string xmlStringSafe;
+
+       // Tranverse through the catacombs of the response to get our ETag for the file and
+       // the server syncronisation token.
+
+       // Start by getting all the server ETag data.
+
+       for (nodeLevel1 = xmlCardDAVDoc->children;
+               nodeLevel1 != NULL;
+               nodeLevel1 = nodeLevel1->next)
+       {
+
+               for (nodeLevel2 = nodeLevel1->children;
+                       nodeLevel2 != NULL;
+                       nodeLevel2 = nodeLevel2->next)
+               {
+
+                       for (nodeLevel3 = nodeLevel2->children;
+                       nodeLevel3 != NULL;
+                       nodeLevel3 = nodeLevel3->next)
+                       {
+
+                               DataFileStatus = 0;
+                               bool HREFFound = FALSE;
+                               bool ETagFound = FALSE;
+                               bool HTTPStatus = FALSE;
+
+                               if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||
+                               !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||
+                               !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")
+                               ){
+
+                                       // Get the filename.
+                                       
+                                       for (nodeLevel4 = nodeLevel3->children;
+                                       nodeLevel4 != NULL;
+                                       nodeLevel4 = nodeLevel4->next)
+                                       {
+                                       
+                                               if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||
+                                               !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||
+                                               !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")
+                                               ){
+                                               
+                                                       DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);
+                                                       wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));
+                                               
+                                                       while (wSTDFilename.HasMoreTokens()){
+                                                       
+                                                               DataFilename = wSTDFilename.GetNextToken();
+                                                       
+                                                       }
+                                                       
+                                                       HREFFound = TRUE;
+                                               
+                                               }
+                                               
+       
+                                       
+                                       }
+                                       
+
+                               } else {
+
+                                       for (nodeLevel4 = nodeLevel3->children;
+                                       nodeLevel4 != NULL;
+                                       nodeLevel4 = nodeLevel4->next)
+                                       {
+
+                                               for (nodeStatusLv1 = nodeLevel3->children;
+                                                       nodeStatusLv1 != NULL;
+                                                       nodeStatusLv1 = nodeStatusLv1->next)
+                                               {
+
+                                                       if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){
+               
+                                                               DataFileStatus = 2;
+                                                                               
+                                                               HTTPStatus = TRUE;
+                                                                               
+                                                       }
+                                       
+                                                       if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") ||
+                                                       !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") ||
+                                                       !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE)
+                                                       {
+
+                                                               // Get the filename.
+                                       
+                                                               for (nodeStatusLv2 = nodeStatusLv1->children;
+                                                               nodeStatusLv2 != NULL;
+                                                               nodeStatusLv2 = nodeStatusLv2->next)
+                                                               {
+                                       
+                                                                       if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") ||
+                                                                       !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") ||
+                                                                       !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text")
+                                                                       ){
+
+                                                                               if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){
+                                                                       
+                                                                                       DataFileStatus = 1;
+                                                                                       
+                                                                                       HTTPStatus = TRUE;
+                                                                       
+                                                                               // This is currently in a WebDAV draft and may hopefully be enabled when this changes.
+                                                                       
+                                                                               //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){
+                                                                               
+                                                                               //      DataFileStatus = 0;
+                                                                               
+                                                                               }
+                                               
+                                                                       }
+                                               
+       
+                                       
+                                                               }
+                                                       
+                                                       }
+
+                                       
+                                               }
+                                               
+                                               for (nodeLevel5 = nodeLevel4->children;
+                                               nodeLevel5 != NULL;
+                                               nodeLevel5 = nodeLevel5->next)
+                                               {
+
+                                                       if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||
+                                                       !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||
+                                                       !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")
+                                                       ){
+
+                                                               for (nodeLevel6 = nodeLevel5->children;
+                                                               nodeLevel6 != NULL;
+                                                               nodeLevel6 = nodeLevel6->next)
+                                                               {
+
+                                                                       // Strip the quotes from the ETag.
+                                               
+                                                                       ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);
+                                                                       if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){
+                                               
+                                                                               ETagData.Remove(0, 1);
+                                                                               ETagData.RemoveLast();
+                                               
+                                                                       }
+                                                               
+                                                                       ETagFound = TRUE;
+
+                                                               }
+                                                               
+                                                       }
+
+                                               }       
+
+                                       }
+
+                               }
+
+                               if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){
+                               
+                                       // Add to the map data.
+                                       
+                                       FileSyncData SData;
+                                       
+                                       SData.ETagData = ETagData;
+                                       SData.DataFlag = DataFileStatus;
+                                       
+                                       ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));
+                               
+                               }
+                               
+                               // Reset the values.
+                               
+                               HREFFound = FALSE;
+                               ETagFound = FALSE;
+                               HTTPStatus = FALSE;
+
+                       }
+
+                       if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") ||
+                       !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") ||
+                       !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) &&
+                       SyncTokenFound == FALSE
+                       ){
+
+                               for (nodeLevel3 = nodeLevel2->children;
+                               nodeLevel3 != NULL;
+                               nodeLevel3 = nodeLevel3->next)
+                               {
+
+                                       if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") ||
+                                       !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") ||
+                                       !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text")
+                                       ){
+                       
+                                               DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content);
+
+                                               SyncTokenFound = TRUE;
+                       
+                                       }
+                       
+                               }
+       
+                       }
+
+               }
+
+       }
+       
+       for (nodeLevel1 = xmlCardDAVDoc->children;
+               nodeLevel1 != NULL;
+               nodeLevel1 = nodeLevel1->next)
+       {
+
+               for (nodeLevel2 = nodeLevel1->children;
+                       nodeLevel2 != NULL;
+                       nodeLevel2 = nodeLevel2->next)
+               {
+
+                       DataFileStatus = 0;
+                       bool HREFFound = FALSE;
+                       bool ETagFound = FALSE;
+                       bool HTTPStatus = FALSE;
+
+                       for (nodeLevel3 = nodeLevel2->children;
+                       nodeLevel3 != NULL;
+                       nodeLevel3 = nodeLevel3->next)
+                       {
+
+                               if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||
+                               !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||
+                               !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")
+                               ){
+
+                                       // Get the filename.
+                                       
+                                       for (nodeLevel4 = nodeLevel3->children;
+                                       nodeLevel4 != NULL;
+                                       nodeLevel4 = nodeLevel4->next)
+                                       {
+                                       
+                                               if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||
+                                               !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||
+                                               !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")
+                                               ){
+                                               
+                                                       DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);
+                                                       wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));
+                                               
+                                                       while (wSTDFilename.HasMoreTokens()){
+                                                       
+                                                               DataFilename = wSTDFilename.GetNextToken();
+                                                       
+                                                       }
+                                                       
+                                                       HREFFound = TRUE;
+                                               
+                                               }
+                                               
+       
+                                       
+                                       }
+                                       
+
+                               } else {
+
+                                       for (nodeLevel4 = nodeLevel3->children;
+                                       nodeLevel4 != NULL;
+                                       nodeLevel4 = nodeLevel4->next)
+                                       {
+
+                                               for (nodeStatusLv1 = nodeLevel3->children;
+                                                       nodeStatusLv1 != NULL;
+                                                       nodeStatusLv1 = nodeStatusLv1->next)
+                                               {
+
+                                                       if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){
+               
+                                                               DataFileStatus = 2;
+
+                                                               HTTPStatus = TRUE;
+                                                                               
+                                                       }
+                                       
+                                                       if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") ||
+                                                       !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") ||
+                                                       !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE)
+                                                       {
+
+                                                               // Get the filename.
+                                       
+                                                               for (nodeStatusLv2 = nodeStatusLv1->children;
+                                                               nodeStatusLv2 != NULL;
+                                                               nodeStatusLv2 = nodeStatusLv2->next)
+                                                               {
+                                       
+                                                                       if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") ||
+                                                                       !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") ||
+                                                                       !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text")
+                                                                       ){
+
+                                                                               if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){
+
+                                                                                       DataFileStatus = 1;
+                                                                                       
+                                                                                       HTTPStatus = TRUE;
+                                                                       
+                                                                               // This is currently in a WebDAV draft and may hopefully be enabled when this changes.
+                                                                       
+                                                                               //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){
+                                                                               
+                                                                               //      DataFileStatus = 0;
+                                                                               
+                                                                               }
+                                               
+                                                                       }
+                                               
+       
+                                       
+                                                               }
+                                                       
+                                                       }
+
+                                       
+                                               }
+                                               
+                                               for (nodeLevel5 = nodeLevel4->children;
+                                               nodeLevel5 != NULL;
+                                               nodeLevel5 = nodeLevel5->next)
+                                               {
+
+                                                       if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||
+                                                       !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||
+                                                       !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")
+                                                       ){
+
+                                                               for (nodeLevel6 = nodeLevel5->children;
+                                                               nodeLevel6 != NULL;
+                                                               nodeLevel6 = nodeLevel6->next)
+                                                               {
+
+                                                                       // Strip the quotes from the ETag.
+                                               
+                                                                       ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);
+                                                                       if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){
+                                               
+                                                                               ETagData.Remove(0, 1);
+                                                                               ETagData.RemoveLast();
+                                               
+                                                                       }
+                                                               
+                                                                       ETagFound = TRUE;
+
+                                                               }
+                                                               
+                                                       }
+
+                                               }       
+
+                                       }
+
+                               }
+
+                       }
+
+                       if (HREFFound == TRUE && HTTPStatus == TRUE && DataFileStatus == 2){
+                       
+                               FileSyncData SData;
+                                       
+                               SData.ETagData = wxT("");
+                               SData.DataFlag = DataFileStatus;
+                                       
+                               ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));                          
+                       
+                       }
+
+                       if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){
+                               
+                               // Add to the map data.
+                                       
+                               FileSyncData SData;
+                                       
+                               SData.ETagData = ETagData;
+                               SData.DataFlag = DataFileStatus;
+                                       
+                               ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));
+                               
+                       }
+                               
+                       // Reset the values.
+                               
+                       HREFFound = FALSE;
+                       ETagFound = FALSE;
+                       HTTPStatus = FALSE;
+                       DataFilename.Clear();
+
+                       if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") ||
+                       !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") ||
+                       !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) &&
+                       SyncTokenFound == FALSE
+                       ){
+
+                               for (nodeLevel3 = nodeLevel2->children;
+                               nodeLevel3 != NULL;
+                               nodeLevel3 = nodeLevel3->next)
+                               {
+
+                                       if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") ||
+                                       !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") ||
+                                       !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text")
+                                       ){
+                       
+                                               DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content);
+
+                                               SyncTokenFound = TRUE;
+                       
+                                       }
+                       
+                               }
+       
+                       }
+
+               }
+
+       }
+       
+       // Get the sync token.
+       
+       if (SyncTokenFound == TRUE){
+       
+               ContactListFinal.SyncToken = DataSyncToken;
+       
+       } else {
+       
+       }
+
+       SleepFor(2000000000);
+
+       /*timespec n1, n2;
+                                               
+       n1.tv_sec = 0;
+       n1.tv_nsec = 2000000000L;
+               
+       nanosleep(&n1, &n2);*/
+
+       xmlFreeDoc(xmlCardDAVDoc);
+       curl_easy_cleanup(conn);
+
+       SyncDataBuffer.reset();
+
+       // Get the first result.
+
+       return ContactListFinal;
+
+}
\ No newline at end of file
diff --git a/source/carddav/carddav-defaultadrurl.cpp b/source/carddav/carddav-defaultadrurl.cpp
new file mode 100644 (file)
index 0000000..f258d69
--- /dev/null
@@ -0,0 +1,663 @@
+#include "carddav.h"
+#include "../version.h"
+#include <wx/wx.h>
+#include <wx/tokenzr.h>
+#include <wx/ffile.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <map>
+#include <thread>
+#include "../vcard/vcard.h"
+#include "../common/dirs.h"
+
+wxString CardDAV::GetDefaultAddressBookURL(){
+
+       // First: Get the principal UID address.
+       
+       PageData.Clear();
+       PageHeader.Clear();
+
+       SSLStatus = TRUE;
+       AuthPassed = TRUE;
+       AbortConnection = FALSE;
+
+       CURL *conn;
+       CURLcode conncode;
+       wxString ServerAddressURL;
+       wxString ServerAuth;
+       wxString ServerAddressSSL;
+       wxString ServerAddressNormal;   
+
+       conn = curl_easy_init();
+       
+       struct curl_slist *connhd = NULL;
+       struct curl_slist *connhd2 = NULL;
+       struct curl_slist *connhd3 = NULL;
+
+       connhd = curl_slist_append(connhd, "Depth: 0");
+       connhd = curl_slist_append(connhd, "Prefer: return-minimal");
+       connhd = curl_slist_append(connhd, "Content-Type: application/xml; charset=utf-8");
+
+       connhd2 = curl_slist_append(connhd2, "Depth: 0");
+       connhd2 = curl_slist_append(connhd2, "Prefer: return-minimal");
+       connhd2 = curl_slist_append(connhd2, "Content-Type: application/xml; charset=utf-8");
+
+       connhd3 = curl_slist_append(connhd3, "Depth: 1");
+       connhd3 = curl_slist_append(connhd3, "Prefer: return-minimal");
+       connhd3 = curl_slist_append(connhd3, "Content-Type: application/xml; charset=utf-8");
+
+       struct CardDAVCURLPasser {
+       
+               CardDAV *Data;
+               bool HeaderMode = TRUE;
+       
+       } CardDAVHeader, CardDAVFooter;
+
+       CardDAVHeader.Data = this;
+       CardDAVHeader.HeaderMode = TRUE;
+       
+       CardDAVFooter.Data = this;
+       CardDAVFooter.HeaderMode = FALSE;
+
+       wxString Data1;
+       wxString Data2;
+       
+       wxString ETag;
+       wxString ETagOriginal;
+       wxString ETagServer;
+       
+       ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
+       ServerAddressSSL = wxT("https://") + ServerAddressURL;
+       ServerAddressNormal = wxT("http://") + ServerAddressURL;
+       
+       ServerAuth = ServerUser + wxT(":") + ServerPass;
+       
+       wxString SAURLPrincipals;
+       wxString SAURLPrincipalURL;
+       wxString SAURLAddressURL;
+       
+       if (ServerSSL){
+       
+               SAURLPrincipals = ServerAddressSSL + wxT("principals/");
+               SAURLPrincipalURL = ServerAddressSSL;
+               SAURLAddressURL = ServerAddressSSL;
+       
+       } else {
+       
+               SAURLPrincipals = ServerAddressNormal + wxT("principals/");
+               SAURLPrincipalURL = ServerAddressNormal;
+               SAURLAddressURL = ServerAddressNormal;
+       
+       }
+       
+       wxString FinalPrefix;
+
+       struct UploadDataStruc UploadData;
+       
+       // Setup the first query finding out where the principal URL is.
+       
+       const char* query = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+               "<D:propfind xmlns:D=\"DAV:\">\n"
+               " <D:prop>"
+               "  <D:current-user-principal/>\n"
+               " </D:prop>"
+               "</D:propfind>";
+
+       // Setup the second query finding out where the address book home URL is.
+       
+       const char* query2 = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+       "<D:propfind xmlns:D=\"DAV:\""
+       "  xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"
+       "  <D:prop>\n"
+       "    <C:addressbook-home-set/>\n"
+       "  </D:prop>\n"
+       "</D:propfind>";
+       
+       // Setup the third query finding out where the default address book URL is.
+       
+       const char* query3 = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+       "<D:propfind xmlns:D=\"DAV:\""
+       "  xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"
+       "  <D:prop>\n"
+       "    <C:default-addressbook-URL/>\n"    
+       "  </D:prop>\n"
+       "</D:propfind>";
+       
+       if (ServerSSL){
+
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipals.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
+               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd);
+               
+               if (AllowSelfSign == TRUE){
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L);
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L);
+               }
+
+               conncode = (curl_easy_perform(conn));
+
+               if (conncode == CURLE_OK){
+
+                       *ServerResult = TRUE;
+                       AuthPassed = TRUE;
+                       ValidResponse = TRUE;
+                       SSLStatus = TRUE;
+
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));                                  
+                                       
+                       *ServerResult = FALSE;
+                       
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);
+                       
+                       return wxT("");                                 
+
+               }
+
+       } else {
+       
+               // No SSL.
+
+               // Do an initial connection (incase of Digest authentication).
+
+               PageData.Clear();
+               PageHeader.Clear();
+
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipals.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
+               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd);
+               
+               conncode = (curl_easy_perform(conn));
+
+               // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG,
+               // then bring up the conflict resolution form.
+               
+               if (EditMode == TRUE){
+               
+               }
+
+               if (conncode == CURLE_OK){
+
+               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
+
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);
+               
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+
+                       fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",
+                                       GetHTTPCode());
+
+                       return wxT("");
+               
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+                       return wxT("");
+
+               }
+
+       }
+       
+       // Process the XML data from the application.
+       
+       xmlDocPtr xmlCardDAVDoc;
+       xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);
+
+       xmlNodePtr nodeLevel1;
+       xmlNodePtr nodeLevel2;
+       xmlNodePtr nodeLevel3;
+       xmlNodePtr nodeLevel4;
+       xmlNodePtr nodeLevel5;
+       xmlNodePtr nodeLevel6;
+       xmlNodePtr nodeLevel7;
+               
+       for (nodeLevel1 = xmlCardDAVDoc->children;
+               nodeLevel1 != NULL;
+               nodeLevel1 = nodeLevel1->next)
+       {
+
+               for (nodeLevel2 = nodeLevel1->children;
+                       nodeLevel2 != NULL;
+                       nodeLevel2 = nodeLevel2->next)
+               {
+
+
+                       for (nodeLevel3 = nodeLevel2->children;
+                       nodeLevel3 != NULL;
+                       nodeLevel3 = nodeLevel3->next)
+                       {
+                       
+                               for (nodeLevel4 = nodeLevel3->children;
+                               nodeLevel4 != NULL;
+                               nodeLevel4 = nodeLevel4->next)
+                               {
+                       
+                                       for (nodeLevel5 = nodeLevel4->children;
+                                       nodeLevel5 != NULL;
+                                       nodeLevel5 = nodeLevel5->next)
+                                       {
+                       
+                                               for (nodeLevel6 = nodeLevel5->children;
+                                               nodeLevel6 != NULL;
+                                               nodeLevel6 = nodeLevel6->next)
+                                               {
+                       
+                                                       if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
+                                                       !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
+                                                       !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
+                                                       ){
+                       
+                                                               // Found the <href> part so extract the principal URL address.
+                                                               
+                                                               for (nodeLevel7 = nodeLevel6->children;
+                                                               nodeLevel7 != NULL;
+                                                               nodeLevel7 = nodeLevel7->next)
+                                                               {
+                                                               
+                                                                       SAURLPrincipalURL.Append(wxString::FromUTF8((const char*)nodeLevel7->content));
+                       
+                                                               }
+                       
+                                                       }
+                       
+                                               }
+                       
+                                       }
+                       
+                               }
+                       
+                       }
+               
+               }
+               
+       }
+       
+       xmlFreeDoc(xmlCardDAVDoc);
+       PageData.Clear();
+       PageHeader.Clear();
+               
+       // Second: Get the addressbook-home-set 
+
+       curl_easy_reset(conn);
+
+       if (ServerSSL){
+
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipalURL.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query2);
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query2));
+               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd2);
+
+               if (AllowSelfSign == TRUE){
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L);
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L);
+               }
+
+               conncode = (curl_easy_perform(conn));
+
+               if (conncode == CURLE_OK){
+
+                       *ServerResult = TRUE;
+                       AuthPassed = TRUE;
+                       SSLStatus = TRUE;
+
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));                                  
+                                       
+                       *ServerResult = FALSE;
+                       ValidResponse = FALSE;
+                       
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);
+                       
+                       return wxT("");                                 
+
+               }
+
+       } else {
+       
+       // No SSL.
+               
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipalURL.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query2);
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query2));
+               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd2);
+               
+               conncode = (curl_easy_perform(conn));
+               
+               // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG,
+               // then bring up the conflict resolution form.
+               
+               if (EditMode == TRUE){
+               
+               }
+
+               if (conncode == CURLE_OK){
+
+               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
+
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);
+               
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+
+                       fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",
+                                       GetHTTPCode());
+                       
+                       ValidResponse = FALSE;
+                       
+                       return wxT("");
+               
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+                       
+                       ValidResponse = FALSE;
+                       
+                       return wxT("");
+
+               }
+               
+       }
+
+       xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);
+               
+       for (nodeLevel1 = xmlCardDAVDoc->children;
+               nodeLevel1 != NULL;
+               nodeLevel1 = nodeLevel1->next)
+       {
+
+               for (nodeLevel2 = nodeLevel1->children;
+                       nodeLevel2 != NULL;
+                       nodeLevel2 = nodeLevel2->next)
+               {
+
+
+                       for (nodeLevel3 = nodeLevel2->children;
+                       nodeLevel3 != NULL;
+                       nodeLevel3 = nodeLevel3->next)
+                       {
+                       
+                               for (nodeLevel4 = nodeLevel3->children;
+                               nodeLevel4 != NULL;
+                               nodeLevel4 = nodeLevel4->next)
+                               {
+                       
+                                       for (nodeLevel5 = nodeLevel4->children;
+                                       nodeLevel5 != NULL;
+                                       nodeLevel5 = nodeLevel5->next)
+                                       {
+                       
+                                               for (nodeLevel6 = nodeLevel5->children;
+                                               nodeLevel6 != NULL;
+                                               nodeLevel6 = nodeLevel6->next)
+                                               {
+                       
+                                                       if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
+                                                       !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
+                                                       !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
+                                                       ){
+                       
+                                                               // Found the <href> part so extract the principal URL address.
+                                                               
+                                                               for (nodeLevel7 = nodeLevel6->children;
+                                                               nodeLevel7 != NULL;
+                                                               nodeLevel7 = nodeLevel7->next)
+                                                               {
+                                                               
+                                                                       SAURLAddressURL.Append(wxString::FromUTF8((const char*)nodeLevel7->content));
+                       
+                                                               }
+                       
+                                                       }
+                       
+                                               }
+                       
+                                       }
+                       
+                               }
+                       
+                       }
+               
+               }
+               
+       }
+
+       xmlFreeDoc(xmlCardDAVDoc);
+       PageData.Clear();
+       PageHeader.Clear();
+
+       // Finally: Get the default-addressbook-URL from the addressbook-home-set address.
+               
+       curl_easy_reset(conn);
+
+       if (ServerSSL){
+
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLAddressURL.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query3);
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query3));
+               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd3);
+
+               if (AllowSelfSign == TRUE){
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L);
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L);
+               }
+
+               conncode = (curl_easy_perform(conn));
+
+               if (conncode == CURLE_OK){
+
+                       *ServerResult = TRUE;
+                       AuthPassed = TRUE;
+                       SSLStatus = TRUE;
+
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));                                  
+                                       
+                       *ServerResult = FALSE;
+                       ValidResponse = FALSE;
+                       
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);
+                       
+                       return wxT("");                                 
+
+               }
+
+       } else {
+       
+       // No SSL.
+               
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLAddressURL.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query3);
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query3));
+               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd3);
+               
+               conncode = (curl_easy_perform(conn));
+               
+               // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG,
+               // then bring up the conflict resolution form.
+               
+               if (EditMode == TRUE){
+               
+               }
+
+               if (conncode == CURLE_OK){
+
+               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
+
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);
+               
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+
+                       fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",
+                                       GetHTTPCode());
+                                       
+                       ValidResponse = FALSE;
+                                       
+                       return wxT("");
+               
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+                                       
+                       ValidResponse = FALSE;
+                                       
+                       return wxT("");
+
+               }
+               
+       }
+       
+       xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);
+               
+       for (nodeLevel1 = xmlCardDAVDoc->children;
+               nodeLevel1 != NULL;
+               nodeLevel1 = nodeLevel1->next)
+       {
+
+               for (nodeLevel2 = nodeLevel1->children;
+                       nodeLevel2 != NULL;
+                       nodeLevel2 = nodeLevel2->next)
+               {
+
+
+                       for (nodeLevel3 = nodeLevel2->children;
+                       nodeLevel3 != NULL;
+                       nodeLevel3 = nodeLevel3->next)
+                       {
+                       
+                               for (nodeLevel4 = nodeLevel3->children;
+                               nodeLevel4 != NULL;
+                               nodeLevel4 = nodeLevel4->next)
+                               {
+                       
+                                       for (nodeLevel5 = nodeLevel4->children;
+                                       nodeLevel5 != NULL;
+                                       nodeLevel5 = nodeLevel5->next)
+                                       {
+                       
+                                               for (nodeLevel6 = nodeLevel5->children;
+                                               nodeLevel6 != NULL;
+                                               nodeLevel6 = nodeLevel6->next)
+                                               {
+                       
+                                                       if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
+                                                       !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
+                                                       !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
+                                                       ){
+                       
+                                                               // Found the <href> part so extract the principal URL address.
+                                                               
+                                                               for (nodeLevel7 = nodeLevel6->children;
+                                                               nodeLevel7 != NULL;
+                                                               nodeLevel7 = nodeLevel7->next)
+                                                               {
+                                                               
+                                                                       FinalPrefix = wxString::FromUTF8((const char*)nodeLevel7->content);
+                       
+                                                               }
+                       
+                                                       }
+                       
+                                               }
+                       
+                                       }
+                       
+                               }
+                       
+                       }
+               
+               }
+               
+       }
+
+       xmlFreeDoc(xmlCardDAVDoc);
+       PageData.Clear();
+       PageHeader.Clear();
+
+       return FinalPrefix;
+
+}
diff --git a/source/carddav/carddav-processdata.cpp b/source/carddav/carddav-processdata.cpp
new file mode 100644 (file)
index 0000000..f3bfdae
--- /dev/null
@@ -0,0 +1,502 @@
+#include "carddav.h"
+#include "../version.h"
+#include <wx/wx.h>
+#include <wx/tokenzr.h>
+#include <wx/ffile.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <map>
+#include <thread>
+#include "../vcard/vcard.h"
+#include "../common/dirs.h"
+
+void CardDAV::ProcessDataThread(){
+
+       PageData.Clear();
+       PageHeader.Clear();
+
+       SSLStatus = TRUE;
+       AuthPassed = TRUE;
+       AbortConnection = FALSE;
+
+        CURL *conn;
+        CURLcode conncode;
+       wxString ServerAddressURL;
+       wxString ServerAuth;
+       wxString ServerAddressSSL;
+       wxString ServerAddressNormal;   
+
+        conn = curl_easy_init();
+       
+       struct CardDAVCURLPasser {
+       
+               CardDAV *Data;
+               bool HeaderMode = TRUE;
+       
+       } CardDAVHeader, CardDAVFooter;
+
+       CardDAVHeader.Data = this;
+       CardDAVHeader.HeaderMode = TRUE;
+       
+       CardDAVFooter.Data = this;
+       CardDAVFooter.HeaderMode = FALSE;
+
+       wxString Data1;
+       wxString Data2;
+       
+       wxString ETag;
+       wxString ETagOriginal;
+       wxString ETagServer;
+               
+       ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation;
+       ServerAddressSSL = wxT("https://") + ServerAddressURL;
+       ServerAddressNormal = wxT("http://") + ServerAddressURL;
+       
+       ServerAuth = ServerUser + wxT(":") + ServerPass;
+       
+       // Try SSL first.
+
+
+       /*
+       char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];
+       //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());
+       strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));
+       
+       char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];
+       //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       
+       strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));
+
+       char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];
+       //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); 
+       strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));
+       
+       */
+
+       //std::string WriteDataString = std::string(ServerUploadData.mb_str());
+
+       std::map<int,int>::iterator ActIter;
+       struct UploadDataStruc UploadData;
+       
+       
+       ActIter = ActivityListPtr->find((int)ItemIndex);
+       
+       // Update result flag.
+
+       ActIter->second = 1;
+       
+       // Setup the request mode if it is not empty.
+       
+       if (!ServerMethod.IsEmpty()){
+       
+               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, (const char*)ServerMethod.mb_str(wxConvUTF8));
+
+       }
+
+       if (ServerSSL){
+
+               wxString ServerCertFilename;
+               bool MatchingCert = FALSE;
+
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               
+               if (UploadMode == TRUE){
+                       
+                       UploadData.readptr = &ServerUploadData;
+                       UploadData.sizeleft = ServerUploadData.Len();
+                       curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
+                       curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
+                       curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
+               
+               }
+
+               ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
+
+               if (wxFile::Exists(ServerCertFilename) == TRUE){
+               
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
+                       curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
+               
+               }
+
+               //UploadData.readptr = &CardDAVDataQuery;
+               //UploadData.sizeleft = CardDAVDataQuery.Len();
+               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
+               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
+               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
+               
+               //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);
+               
+               claconncode = (curl_easy_perform(conn));
+
+               // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without
+               // the local certificate in use.
+
+               if (claconncode == CURLE_PEER_FAILED_VERIFICATION){
+                       
+                       curl_easy_cleanup(conn);
+                       conn = curl_easy_init();
+                       
+                       curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+                       curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+                       curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                       curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+                       curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+                       curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+                       curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+                       curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                       curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+                       curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+                       curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+                       curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+                       curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+
+                       if (UploadMode == TRUE){
+
+                               UploadData.readptr = &ServerUploadData;
+                               UploadData.sizeleft = ServerUploadData.Len();
+                               curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
+                               curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
+                               curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
+               
+                       }
+                       
+                       claconncode = (curl_easy_perform(conn));
+                       
+                       // If claconncode is CURLE_OK then delete the certificate file as that
+                       // is no longer needed.
+                       
+                       if (claconncode == CURLE_OK){
+                       
+                               // Delete the certificate file.
+                               
+                               wxRemoveFile(ServerCertFilename);
+                       
+                       }
+               
+               }
+
+               // Check if it fails with a CURLE_SSL_CACERT then compare
+               // the certificates as PEM files.
+               
+               if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
+               
+                       //curl_easy_cleanup(conn);
+                       //conn = curl_easy_init();
+
+                       CURL *sslerrconn;
+                       sslerrconn = curl_easy_init();
+                       CURLcode sslerrconncode;
+
+                       //claconncode = (curl_easy_perform(conn));
+
+                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
+
+                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
+                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
+                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
+                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
+                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
+                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
+               
+                       wxString SSLLocalData;
+                       wxString SSLServerData;
+               
+                       sslerrconncode = (curl_easy_perform(sslerrconn));
+               
+                       SSLCertCol = BuildSSLCollection(sslerrconn);
+                       std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);
+                       std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
+                       
+                       wxFFile SSLLocalFile;
+                       
+#if wxABI_VERSION < 20900
+                       SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
+#else
+                       SSLLocalFile.Open(ServerCertFilename, wxT("r"));
+#endif 
+       
+                       // Load the recovery database for tasks not done.
+       
+                       if (SSLLocalFile.IsOpened() == TRUE){
+
+                       // Check if we are using wxWidgets version 2.8 or less and
+                       // execute the required command accordingly.
+       
+                               SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
+               
+       
+                       }
+                       
+                       SSLServerData = SSLDataIter->second;
+                       
+                       if (SSLLocalData == SSLServerData){
+                       
+                               // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
+                               // and CURLOPT_SSL_VERIFYHOST off.
+                       
+                               curl_easy_cleanup(conn);
+                               conn = curl_easy_init();
+                               
+                               PageData.clear();
+                               PageHeader.clear();
+                       
+                               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+                               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+                               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+                               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+                               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+                               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+                               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+                               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+                               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+                               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+                               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+
+                               if (UploadMode == TRUE){
+
+                                       UploadData.readptr = &ServerUploadData;
+                                       UploadData.sizeleft = ServerUploadData.Len();
+                                       curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
+                                       curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
+                                       curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
+               
+                               }
+                               
+                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);
+                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);
+                       
+                               claconncode = (curl_easy_perform(conn));
+                               
+                               MatchingCert = TRUE;
+                       
+                       }
+                       
+                       if (MatchingCert == FALSE){
+               
+                               claconncode = CURLE_SSL_CACERT;
+                               return;
+               
+                       }
+                       
+                       curl_easy_cleanup(sslerrconn);
+               
+               }
+
+               // Sort out SSL error.
+               
+               // When SSL cert error occurs, connect again and fetch certificates.
+               // Display a message to the user explaining that an invalid
+               // certificate has been given and let the user decide what
+               // to do next.
+
+               if (claconncode == CURLE_OK){
+
+               } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
+               
+                       CURL *sslerrconn;
+                       sslerrconn = curl_easy_init();
+                       CURLcode sslerrconncode;
+               
+                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
+               
+                       // Replace conn with sslerrconn!
+               
+                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
+                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
+                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
+                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
+                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
+                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
+               
+                       sslerrconncode = (curl_easy_perform(sslerrconn));
+
+                       SSLCertCol = BuildSSLCollection(sslerrconn);
+                       SSLCertCol.SuccessCode = 1;
+
+                       return;
+               
+               } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
+               
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(claconncode));
+                       int http_code = 0;
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
+                       fprintf(stderr, "Error code was: %d\n", http_code);
+                                       
+                       return;
+               
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(claconncode));
+                       int http_code = 0;
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
+                       fprintf(stderr, "Error code was: %d\n", http_code);
+
+                       return;
+
+               }
+
+       } else {
+       
+       // No SSL.
+               
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               
+               if (UploadMode == TRUE){
+                       
+                       UploadData.readptr = &ServerUploadData;
+                       UploadData.sizeleft = ServerUploadData.Len();
+                       curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
+                       curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
+                       curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
+               
+               }
+               
+               conncode = (curl_easy_perform(conn));
+
+               if (conncode == CURLE_OK){
+
+                       // Process the server header response and look for
+                       // 'addressbook' within the DAV header.
+                       
+                       wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n"));
+                       wxString wxSHeaderLine;
+                       std::map<int, wxString> DAVHeaderLines;
+                       
+                       while (wxSHeaderLines.HasMoreTokens()){
+                       
+                               wxSHeaderLine = wxSHeaderLines.GetNextToken();
+                               
+                               if (wxSHeaderLine.Mid(0, 5) == wxT("ETag:")){
+                               
+                                       ETagData = wxSHeaderLine.Mid(5);
+                                       ETagData.Trim();
+                                       ETagData.Trim(FALSE);
+                                       
+                                       // Check for commas.
+                                       
+                                       if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){
+                                                       
+                                               ETagData.Remove(0, 1);
+                                               ETagData.RemoveLast();
+                                                       
+                                       }
+                               
+                               }
+                               
+                               if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){
+                               
+                                       // Look for address book in the line.
+                                       
+                                       if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){
+                                       
+                                               HasCalDAVSupport = TRUE;
+                                       
+                                       }
+                               
+                               }
+                       
+                       }
+                       
+                       // Get the ETag from the header.
+                       
+                       if (UploadMode == TRUE){
+               
+                               wxString PageHeaderLine;
+               
+                               wxStringTokenizer PageHeaderSplit(PageHeader, wxT("\r\n"));
+                               
+                               if (PageHeaderSplit.HasMoreTokens()){
+                               
+                                       PageHeaderLine = PageHeaderSplit.GetNextToken();
+                               
+                               }
+               
+                       }
+
+                       ActIter->second = 4;
+                       return;
+
+               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
+
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);
+               
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+
+                       fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",
+                                       GetHTTPCode());
+
+                       ActIter->second = 2;
+                       return;
+               
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+                               
+                       ActIter->second = 2;
+                       return;
+
+               }
+               
+       }
+       
+       // Catch all.
+       
+       //ActIter->second = 1;
+       *ServerResult = TRUE;
+       return;
+
+}
+
+void CardDAV::ProcessData(){
+
+       std::thread ConnectThread(&CardDAV::ProcessDataThread, this);
+       ConnectThread.detach();
+
+}
\ No newline at end of file
diff --git a/source/carddav/carddav-servercontact.cpp b/source/carddav/carddav-servercontact.cpp
new file mode 100644 (file)
index 0000000..3c94d88
--- /dev/null
@@ -0,0 +1,396 @@
+#include "carddav.h"
+#include "../version.h"
+#include <wx/wx.h>
+#include <wx/tokenzr.h>
+#include <wx/ffile.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <map>
+#include <thread>
+#include "../vcard/vcard.h"
+#include "../common/dirs.h"
+
+void CardDAV::GetServerContactData()
+{
+
+       PageData.Clear();
+       PageHeader.Clear();
+
+       SSLStatus = TRUE;
+       AuthPassed = TRUE;
+       AbortConnection = FALSE;
+       
+       wxString ServerCertFilename;
+       bool MatchingCert = FALSE;
+
+        CURL *conn;
+        CURLcode conncode;
+       wxString ServerAddressURL;
+       wxString ServerAuth;
+       wxString ServerAddressSSL;
+       wxString ServerAddressNormal;   
+
+        conn = curl_easy_init();
+       
+       struct CardDAVCURLPasser {
+       
+               CardDAV *Data;
+               bool HeaderMode = TRUE;
+       
+       } CardDAVHeader, CardDAVFooter;
+
+       CardDAVHeader.Data = this;
+       CardDAVHeader.HeaderMode = TRUE;
+       
+       CardDAVFooter.Data = this;
+       CardDAVFooter.HeaderMode = FALSE;
+
+       wxString Data1;
+       wxString Data2;
+       
+       ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation;
+       ServerAddressSSL = wxT("https://") + ServerAddressURL;
+       ServerAddressNormal = wxT("http://") + ServerAddressURL;
+       
+       ServerAuth = ServerUser + wxT(":") + ServerPass;
+       
+       // Try SSL first.
+
+
+       /*
+       char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];
+       //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());
+       strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));
+       
+       char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];
+       //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       
+       strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));
+
+       char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];
+       //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); 
+       strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));
+       
+       */
+
+       //std::string WriteDataString = std::string(ServerUploadData.mb_str());
+
+       std::map<int,int>::iterator ActIter;
+       struct UploadDataStruc UploadData;
+       
+       
+       ActIter = ActivityListPtr->find((int)ItemIndex);
+
+       //ActIter->second = 1;
+
+       /*wxString CardDAVDataQuery = wxT("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n");
+       CardDAVDataQuery.Append(wxT("<C:addressbook-multiget xmlns:D=\"DAV:\"\r\n"));
+       CardDAVDataQuery.Append(wxT("   xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\r\n"));
+       CardDAVDataQuery.Append(wxT("<D:prop><D:getetag/>\r\n"));
+       CardDAVDataQuery.Append(wxT("<C:address-data>\r\n"));
+       CardDAVDataQuery.Append(wxT("   <C:allprop/>\r\n"));
+       CardDAVDataQuery.Append(wxT("</C:address-data></D:prop>\r\n"));
+       CardDAVDataQuery.Append(wxT("</C:addressbook-multiget>"));*/
+
+       if (ServerSSL){
+
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               
+               //UploadData.readptr = &CardDAVDataQuery;
+               //UploadData.sizeleft = CardDAVDataQuery.Len();
+               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
+               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
+               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
+
+               ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
+
+               if (wxFile::Exists(ServerCertFilename) == TRUE){
+               
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
+                       curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
+               
+               }
+
+               claconncode = (curl_easy_perform(conn));
+
+               // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without
+               // the local certificate in use.
+
+               if (claconncode == CURLE_PEER_FAILED_VERIFICATION){
+                       
+                       curl_easy_cleanup(conn);
+                       conn = curl_easy_init();
+                       
+                       curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+                       curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
+                       curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                       curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+                       curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+                       curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
+                       curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+                       curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                       curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+                       curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+                       curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               
+                       //UploadData.readptr = &CardDAVDataQuery;
+                       //UploadData.sizeleft = CardDAVDataQuery.Len();
+                       
+                       claconncode = (curl_easy_perform(conn));
+                       
+                       // If claconncode is CURLE_OK then delete the certificate file as that
+                       // is no longer needed.
+                       
+                       if (claconncode == CURLE_OK){
+                       
+                               // Delete the certificate file.
+                               
+                               wxRemoveFile(ServerCertFilename);
+                       
+                       }
+               
+               }
+
+               // Check if it fails with a CURLE_SSL_CACERT then compare
+               // the certificates as PEM files.
+               
+               if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
+               
+                       //curl_easy_cleanup(conn);
+                       //conn = curl_easy_init();
+
+                       CURL *sslerrconn;
+                       sslerrconn = curl_easy_init();
+                       CURLcode sslerrconncode;
+
+                       //claconncode = (curl_easy_perform(conn));
+
+                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
+
+                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 1L);
+                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
+                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
+                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);               
+                       curl_easy_setopt(sslerrconn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
+               
+                       //UploadData.readptr = &CardDAVDataQuery;
+                       //UploadData.sizeleft = CardDAVDataQuery.Len();
+                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYHOST, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
+               
+                       wxString SSLLocalData;
+                       wxString SSLServerData;
+               
+                       sslerrconncode = (curl_easy_perform(sslerrconn));
+               
+                       SSLCertCol = BuildSSLCollection(sslerrconn);
+                       std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);
+                       std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
+                       
+                       wxFFile SSLLocalFile;
+                       
+#if wxABI_VERSION < 20900
+                       SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
+#else
+                       SSLLocalFile.Open(ServerCertFilename, wxT("r"));
+#endif 
+       
+                       // Load the recovery database for tasks not done.
+       
+                       if (SSLLocalFile.IsOpened() == TRUE){
+       
+                               SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
+               
+       
+                       }
+                       
+                       SSLServerData = SSLDataIter->second;
+                       
+                       if (SSLLocalData == SSLServerData){
+                       
+                               // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
+                               // and CURLOPT_SSL_VERIFYHOST off.
+                       
+                               curl_easy_cleanup(conn);
+                               conn = curl_easy_init();
+                               
+                               PageData.clear();
+                               PageHeader.clear();
+                       
+                               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+                               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
+                               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+                               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+                               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
+                               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+                               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+                               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+                               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               
+                               //UploadData.readptr = &CardDAVDataQuery;
+                               //UploadData.sizeleft = CardDAVDataQuery.Len();
+                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);
+                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);
+                                                       
+                               claconncode = (curl_easy_perform(conn));
+                               
+                               MatchingCert = TRUE;
+                       
+                       }
+                       
+                       if (MatchingCert == FALSE){
+               
+                               claconncode = CURLE_SSL_CACERT;
+                               return;
+               
+                       }
+                       
+                       curl_easy_cleanup(sslerrconn);
+               
+               }
+               
+               // Sort out SSL error.
+               
+               // When SSL cert error occurs, connect again and fetch certificates.
+               // Display a message to the user explaining that an invalid
+               // certificate has been given and let the user decide what
+               // to do next.
+
+               if (claconncode == CURLE_OK){
+
+               } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
+               
+                       CURL *sslerrconn;
+                       sslerrconn = curl_easy_init();
+                       CURLcode sslerrconncode;
+               
+                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
+               
+                       // Replace conn with sslerrconn!
+               
+                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
+                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
+                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
+                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
+                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
+                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
+                                       
+                       sslerrconncode = (curl_easy_perform(sslerrconn));
+
+                       SSLCertCol = BuildSSLCollection(sslerrconn);
+                       SSLCertCol.SuccessCode = 1;
+
+                       return;
+               
+               } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
+               
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(claconncode));
+                       int http_code = 0;
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
+                       fprintf(stderr, "Error code was: %d\n", http_code);
+                                       
+                       return;
+               
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(claconncode));
+                       int http_code = 0;
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
+                       fprintf(stderr, "Error code was: %d\n", http_code);
+
+                       return;
+
+               }
+               
+       } else {
+       
+               // No SSL.
+               
+               wxString EmptyString;
+               
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+               
+               //UploadData.readptr = &CardDAVDataQuery;
+               //UploadData.sizeleft = CardDAVDataQuery.Len();
+               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
+               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
+               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
+
+               //UploadData.readptr = &CardDAVDataQuery;
+               //UploadData.sizeleft = CardDAVDataQuery.Len();
+               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
+               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
+               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
+               
+               //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);     
+               
+               PageData.Clear();
+               PageHeader.Clear();
+               
+               conncode = (curl_easy_perform(conn));
+
+               if (conncode == CURLE_OK){
+
+               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
+               
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+                                       
+                       fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",
+                                       GetHTTPCode());
+                                       
+                       return;
+               
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+                               
+                       return;
+
+               }
+               
+       }
+       
+       return;
+
+}
\ No newline at end of file
diff --git a/source/carddav/carddav-serveretag.cpp b/source/carddav/carddav-serveretag.cpp
new file mode 100644 (file)
index 0000000..85b0e15
--- /dev/null
@@ -0,0 +1,585 @@
+#include "carddav.h"
+#include "../version.h"
+#include <wx/wx.h>
+#include <wx/tokenzr.h>
+#include <wx/ffile.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <map>
+#include <thread>
+#include "../vcard/vcard.h"
+#include "../common/dirs.h"
+
+void CardDAV::GetServerETagValueThread()
+{
+
+       PageData.Clear();
+       PageHeader.Clear();
+
+       SSLStatus = TRUE;
+       AuthPassed = TRUE;
+       AbortConnection = FALSE;
+       
+       bool FilenameIsDirectory = FALSE;
+        CURL *conn;
+        CURLcode conncode;
+       wxString ServerAddressURL;
+       wxString ServerAuth;
+       wxString ServerAddressSSL;
+       wxString ServerAddressNormal;   
+
+        conn = curl_easy_init();
+       
+       struct CardDAVCURLPasser {
+       
+               CardDAV *Data;
+               bool HeaderMode = TRUE;
+       
+       } CardDAVHeader, CardDAVFooter;
+
+       CardDAVHeader.Data = this;
+       CardDAVHeader.HeaderMode = TRUE;
+       
+       CardDAVFooter.Data = this;
+       CardDAVFooter.HeaderMode = FALSE;
+
+       wxString Data1;
+       wxString Data2;
+       
+       ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation;
+       ServerAddressSSL = wxT("https://") + ServerAddressURL;
+       ServerAddressNormal = wxT("http://") + ServerAddressURL;
+       
+       ServerAuth = ServerUser + wxT(":") + ServerPass;
+       
+       // Workout if path is directory or filename.
+       
+       /*if (ServerAddress){
+               FilenameIsDirectory = TRUE;
+       } else {
+               FilenameIsDirectory = FALSE;
+       }*/
+       
+       // Try SSL first.
+
+
+       /*
+       char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];
+       //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());
+       strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));
+       
+       char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];
+       //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       
+       strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));
+
+       char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];
+       //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); 
+       strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));
+       
+       */
+
+       //std::string WriteDataString = std::string(ServerUploadData.mb_str());
+
+       std::map<int,int>::iterator ActIter;
+       struct UploadDataStruc UploadData;
+       
+       
+       ActIter = ActivityListPtr->find((int)ItemIndex);
+       
+       static const char* query =
+       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
+       "<C:addressbook-query xmlns:D=\"DAV:\""
+       "       xmlns:C=\"urn:ietf:params:xml:ns:carddav\">"
+       "<D:prop><D:getetag/>"
+       //"<C:address-data>"
+       //"     <C:allprop/>"
+       //"</C:address-data></D:prop>"
+       "</D:prop>"
+       "<C:filter/>"
+       "</C:addressbook-query>";
+
+       if (ServerSSL){
+
+               wxString ServerCertFilename;
+               bool MatchingCert = FALSE;
+
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+
+               //UploadData.readptr = &CardDAVDataQuery;
+               //UploadData.sizeleft = CardDAVDataQuery.Len();
+               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
+               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
+               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
+               
+               //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
+
+               ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
+
+               if (wxFile::Exists(ServerCertFilename) == TRUE){
+               
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
+                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
+                       curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
+               
+               }
+
+               claconncode = (curl_easy_perform(conn));
+
+               // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without
+               // the local certificate in use.
+
+               if (claconncode == CURLE_PEER_FAILED_VERIFICATION){
+                       
+                       curl_easy_cleanup(conn);
+                       conn = curl_easy_init();
+                       
+                       curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+                       curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+                       curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                       curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+                       curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+                       curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+                       curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+                       curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                       curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+                       curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+                       curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+                       curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+                       curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
+                       curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+                       curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
+                       curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
+                       
+                       claconncode = (curl_easy_perform(conn));
+                       
+                       // If claconncode is CURLE_OK then delete the certificate file as that
+                       // is no longer needed.
+                       
+                       if (claconncode == CURLE_OK){
+                       
+                               // Delete the certificate file.
+                               
+                               wxRemoveFile(ServerCertFilename);
+                       
+                       }
+               
+               }
+
+               // Check if it fails with a CURLE_SSL_CACERT then compare
+               // the certificates as PEM files.
+               
+               if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
+               
+                       //curl_easy_cleanup(conn);
+                       //conn = curl_easy_init();
+
+                       CURL *sslerrconn;
+                       sslerrconn = curl_easy_init();
+                       CURLcode sslerrconncode;
+
+                       //claconncode = (curl_easy_perform(conn));
+
+                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
+
+                       PageData.clear();
+                       PageHeader.clear();
+
+                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
+                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
+                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
+                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
+                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
+                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
+                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 1);
+                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYHOST, 2);
+                       curl_easy_setopt(sslerrconn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
+               
+                       wxString SSLLocalData;
+                       wxString SSLServerData;
+               
+                       sslerrconncode = (curl_easy_perform(sslerrconn));
+               
+                       SSLCertCol = BuildSSLCollection(sslerrconn);
+                       std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);
+                       std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
+                       
+                       wxFFile SSLLocalFile;
+                       
+#if wxABI_VERSION < 20900
+                       SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
+#else
+                       SSLLocalFile.Open(ServerCertFilename, wxT("r"));
+#endif 
+
+                       // Load the recovery database for tasks not done.
+       
+                       if (SSLLocalFile.IsOpened() == TRUE){
+
+                       // Check if we are using wxWidgets version 2.8 or less and
+                       // execute the required command accordingly.
+       
+                               SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
+               
+       
+                       }
+                       
+                       SSLServerData = SSLDataIter->second;
+                       
+                       if (SSLLocalData == SSLServerData){
+                       
+                               // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
+                               // and CURLOPT_SSL_VERIFYHOST off.
+                       
+                               curl_easy_cleanup(conn);
+                               conn = curl_easy_init();
+                               
+                               PageData.clear();
+                               PageHeader.clear();
+                       
+                               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+                               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+                               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+                               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+                               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+                               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+                               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+                               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+                               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+                               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+                               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
+                               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+                               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
+                               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
+                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);
+                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);              
+                       
+                               claconncode = (curl_easy_perform(conn));
+                               
+                               MatchingCert = TRUE;
+                       
+                       }
+                       
+                       if (MatchingCert == FALSE){
+               
+                               claconncode = CURLE_SSL_CACERT;
+                               return;
+               
+                       }
+                       
+                       curl_easy_cleanup(sslerrconn);
+               
+               }
+
+               // Sort out SSL error.
+               
+               // When SSL cert error occurs, connect again and fetch certificates.
+               // Display a message to the user explaining that an invalid
+               // certificate has been given and let the user decide what
+               // to do next.
+
+               if (claconncode == CURLE_OK){
+
+               } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
+               
+                       CURL *sslerrconn;
+                       sslerrconn = curl_easy_init();
+                       CURLcode sslerrconncode;
+               
+                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
+               
+                       // Replace conn with sslerrconn!
+               
+                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
+                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
+                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
+                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
+                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
+                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
+                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
+                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
+                                       
+                       sslerrconncode = (curl_easy_perform(sslerrconn));
+
+                       SSLCertCol = BuildSSLCollection(sslerrconn);
+                       SSLCertCol.SuccessCode = 1;
+
+                       curl_easy_cleanup(conn);
+                       curl_easy_cleanup(sslerrconn);
+
+                       return;
+               
+               } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
+               
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(claconncode));
+                       int http_code = 0;
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
+                       fprintf(stderr, "Error code was: %d\n", http_code);
+
+                       curl_easy_cleanup(conn);
+                                       
+                       return;
+               
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(claconncode));
+                       int http_code = 0;
+                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
+                       fprintf(stderr, "Error code was: %d\n", http_code);
+
+                       curl_easy_cleanup(conn);
+
+                       return;
+
+               }
+
+       } else {
+       
+               // No SSL.
+       
+               wxString EmptyString;
+               
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
+               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
+               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
+               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
+               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
+               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
+               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
+               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
+
+               //UploadData.readptr = &CardDAVDataQuery;
+               //UploadData.sizeleft = CardDAVDataQuery.Len();
+               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
+               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
+               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
+               
+               //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
+               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));           
+               
+               PageData.Clear();
+               PageHeader.Clear();
+               
+               conncode = (curl_easy_perform(conn));
+
+               if (conncode == CURLE_OK){
+
+               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
+               
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+                               
+                       return;
+               
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                                       curl_easy_strerror(conncode));
+                               
+                       return;
+
+               }
+               
+       }
+       
+       xmlDocPtr xmlCardDAVDoc;
+
+       xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);
+
+       xmlNodePtr nodeLevel1;
+       xmlNodePtr nodeLevel2;
+       xmlNodePtr nodeLevel3;
+       xmlNodePtr nodeLevel4;
+       xmlNodePtr nodeLevel5;
+       xmlNodePtr nodeLevel6;
+
+       std::map<wxString,wxString> xmlDataMap;
+
+       wxString DataFilename;
+       wxString ETagData;
+
+       std::string xmlStringSafe;
+
+       // Tranverse through the catacombs of the response to get our ETag for the file.
+
+       for (nodeLevel1 = xmlCardDAVDoc->children;
+               nodeLevel1 != NULL;
+               nodeLevel1 = nodeLevel1->next)
+       {
+
+               bool HREFFound = FALSE;
+               bool ETagFound = FALSE;
+
+               for (nodeLevel2 = nodeLevel1->children;
+                       nodeLevel2 != NULL;
+                       nodeLevel2 = nodeLevel2->next)
+               {
+
+                       for (nodeLevel3 = nodeLevel2->children;
+                       nodeLevel3 != NULL;
+                       nodeLevel3 = nodeLevel3->next)
+                       {
+
+                               if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||
+                               !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||
+                               !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")
+                               ){
+
+                                       // Get the filename.
+                                       
+                                       for (nodeLevel4 = nodeLevel3->children;
+                                       nodeLevel4 != NULL;
+                                       nodeLevel4 = nodeLevel4->next)
+                                       {
+                                       
+                                               if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||
+                                               !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||
+                                               !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")
+                                               ){
+
+                                                       DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);
+                                                       wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));
+                                               
+                                                       while (wSTDFilename.HasMoreTokens()){
+                                                       
+                                                               DataFilename = wSTDFilename.GetNextToken();
+                                                       
+                                                       }
+                                                       
+                                                       HREFFound = TRUE;
+                                               
+                                               }
+                                               
+       
+                                       
+                                       }
+
+                               } else {
+
+                                       for (nodeLevel4 = nodeLevel3->children;
+                                       nodeLevel4 != NULL;
+                                       nodeLevel4 = nodeLevel4->next)
+                                       {
+                                                       
+                                                       for (nodeLevel5 = nodeLevel4->children;
+                                                       nodeLevel5 != NULL;
+                                                       nodeLevel5 = nodeLevel5->next)
+                                                       {
+
+                                                               if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||
+                                                               !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||
+                                                               !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")
+                                                               ){
+
+                                                                       for (nodeLevel6 = nodeLevel5->children;
+                                                                       nodeLevel6 != NULL;
+                                                                       nodeLevel6 = nodeLevel6->next)
+                                                                       {
+                                                       
+                                                                               // Strip the quotes from the ETag.
+                                                       
+                                                                               ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);
+                                                                               if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){
+                                                       
+                                                                                       ETagData.Remove(0, 1);
+                                                                                       ETagData.RemoveLast();
+                                                       
+                                                                               }
+                                                                       
+                                                                               ETagFound = TRUE;
+
+                                                                       }
+                                                                       
+                                                               }
+
+                                                       }       
+
+                                       }
+
+                               }
+
+                       }
+
+               }
+               
+               if (HREFFound == TRUE && ETagFound == TRUE){
+                               
+                       // Add to the map data.
+                                       
+                       xmlDataMap.insert(std::make_pair(DataFilename, ETagData));
+                               
+                       HREFFound = FALSE;
+                       ETagFound = FALSE;
+                               
+               }
+
+
+       }
+
+       xmlFreeDoc(xmlCardDAVDoc);
+
+       // Get the first result.
+
+       for (std::map<wxString,wxString>::iterator iter = xmlDataMap.begin(); 
+               iter != xmlDataMap.end(); ++iter){
+       
+               ETagResult = iter->second;
+               break;
+               
+       }
+       
+       if (ETagResult.IsEmpty()){
+       
+               return;
+       
+       }
+       
+       return;
+       
+}
+
+void CardDAV::GetServerETagValue(){
+
+       std::thread ConnectThread(&CardDAV::GetServerETagValueThread, this);
+       ConnectThread.detach();
+
+}
\ No newline at end of file
diff --git a/source/carddav/carddav-sslverify.cpp b/source/carddav/carddav-sslverify.cpp
new file mode 100644 (file)
index 0000000..89998de
--- /dev/null
@@ -0,0 +1,136 @@
+#include "carddav.h"
+#include "../version.h"
+#include <wx/wx.h>
+#include <wx/tokenzr.h>
+#include <wx/ffile.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <map>
+#include <thread>
+#include "../vcard/vcard.h"
+#include "../common/dirs.h"
+
+CURLcode CardDAV::SSLVerifyTest(){
+
+       PageData.Clear();
+       PageHeader.Clear();
+
+       SSLStatus = TRUE;
+       AuthPassed = TRUE;
+       AbortConnection = FALSE;
+
+       CURL *conn;
+       CURL *connssldata;
+       CURLcode conncode;
+       wxString ServerAddressURL;
+       wxString ServerAuth;
+       wxString ServerAddressSSL;
+       wxString ServerAddressNormal;
+
+       conn = curl_easy_init();
+
+       /*struct CardDAVCURLPasser {
+
+               CardDAV *Data;
+               bool HeaderMode = TRUE;
+
+       } CardDAVHeader, CardDAVFooter;
+
+       CardDAVHeader.Data = this;
+       CardDAVHeader.HeaderMode = TRUE;
+
+       CardDAVFooter.Data = this;
+       CardDAVFooter.HeaderMode = FALSE;*/
+
+       wxString Data1;
+       wxString Data2;
+
+       ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
+       ServerAddressSSL = wxT("https://") + ServerAddressURL;
+
+       if (ServerSSL){
+
+               union {
+                       struct curl_slist       *certdata;
+                       struct curl_certinfo    *certinfo;
+               } ptr;
+
+               ptr.certdata = NULL;
+
+               // Setup two initial connections and attempt to get the certificate data.
+
+               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+               curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
+               curl_easy_setopt(conn, CURLOPT_VERBOSE, 1L);
+               //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, FALSE);
+               //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, FALSE);
+               curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, curlerrbuffer);
+               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
+               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
+               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
+
+               conncode = (curl_easy_perform(conn));
+
+               // Check if the SSL certificate is valid or self-signed or some other
+               // error occured.
+
+               if (conncode == CURLE_OK){
+
+                       // Connection is OK. Do nothing.
+
+                       *ServerResult = TRUE;
+
+               } else if (conncode == CURLE_SSL_CACERT || conncode == CURLE_SSL_CONNECT_ERROR){
+
+                       connssldata = curl_easy_init();
+
+                       // Retry but get the certificates without peer/host verification.
+
+                       curl_easy_setopt(connssldata, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
+                       curl_easy_setopt(connssldata, CURLOPT_CERTINFO, 1);
+                       curl_easy_setopt(connssldata, CURLOPT_VERBOSE, 1L);
+                       curl_easy_setopt(connssldata, CURLOPT_ERRORBUFFER, curlerrbuffer);
+                       curl_easy_setopt(connssldata, CURLOPT_WRITEFUNCTION, WritebackFunc);
+                       curl_easy_setopt(connssldata, CURLOPT_WRITEDATA, &PageData);
+                       curl_easy_setopt(connssldata, CURLOPT_WRITEHEADER, &PageHeader);
+                       curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYPEER, 0L);
+                       curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYHOST, 0L);
+
+                       CURLcode certfetchcode;
+
+                       certfetchcode = (curl_easy_perform(connssldata));
+
+                       VerifyCertCollection = BuildSSLCollection(connssldata);
+
+                       if (certfetchcode == CURLE_OK){
+                               
+                               curl_easy_getinfo(connssldata, CURLINFO_CERTINFO, &ptr.certdata);
+
+                               VerifyCertCollection = BuildSSLCollection(connssldata);
+
+                       } else {
+
+                               conncode = certfetchcode;
+
+                       }
+
+                       *ServerResult = FALSE;
+
+               } else {
+
+                       fprintf(stderr, "curl_easy_perform() failed: %s\n",
+                               curl_easy_strerror(conncode));
+
+                       ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));
+
+                       *ServerResult = FALSE;
+
+               }
+
+       }
+
+       curl_easy_cleanup(conn);
+
+       return conncode;
+
+}
\ No newline at end of file
index 33710f8..29f1c70 100644 (file)
@@ -21,12 +21,6 @@ size_t WritebackFunc(char *ptr, size_t size, size_t nmemb, wxString *stream){
 \r
 }\r
 \r
-struct UploadDataStruc{\r
-       wxString *readptr;\r
-       long sizeleft;\r
-       int seek = 0;\r
-};\r
-\r
 int ProgressFunc(void *clientdata, double TTDown, double NDown, double TTUp, double NUp){\r
 \r
        int ProgressRet;\r
@@ -233,131 +227,6 @@ void CardDAV::Abort(){
 \r
 }\r
 \r
-CURLcode CardDAV::SSLVerifyTest(){\r
-\r
-       PageData.Clear();\r
-       PageHeader.Clear();\r
-\r
-       SSLStatus = TRUE;\r
-       AuthPassed = TRUE;\r
-       AbortConnection = FALSE;\r
-\r
-       CURL *conn;\r
-       CURL *connssldata;\r
-       CURLcode conncode;\r
-       wxString ServerAddressURL;\r
-       wxString ServerAuth;\r
-       wxString ServerAddressSSL;\r
-       wxString ServerAddressNormal;\r
-\r
-       conn = curl_easy_init();\r
-\r
-       /*struct CardDAVCURLPasser {\r
-\r
-               CardDAV *Data;\r
-               bool HeaderMode = TRUE;\r
-\r
-       } CardDAVHeader, CardDAVFooter;\r
-\r
-       CardDAVHeader.Data = this;\r
-       CardDAVHeader.HeaderMode = TRUE;\r
-\r
-       CardDAVFooter.Data = this;\r
-       CardDAVFooter.HeaderMode = FALSE;*/\r
-\r
-       wxString Data1;\r
-       wxString Data2;\r
-\r
-       ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
-       ServerAddressSSL = wxT("https://") + ServerAddressURL;\r
-\r
-       if (ServerSSL){\r
-\r
-               union {\r
-                       struct curl_slist       *certdata;\r
-                       struct curl_certinfo    *certinfo;\r
-               } ptr;\r
-\r
-               ptr.certdata = NULL;\r
-\r
-               // Setup two initial connections and attempt to get the certificate data.\r
-\r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);\r
-               curl_easy_setopt(conn, CURLOPT_VERBOSE, 1L);\r
-               //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, FALSE);\r
-               //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, FALSE);\r
-               curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, curlerrbuffer);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-\r
-               conncode = (curl_easy_perform(conn));\r
-\r
-               // Check if the SSL certificate is valid or self-signed or some other\r
-               // error occured.\r
-\r
-               if (conncode == CURLE_OK){\r
-\r
-                       // Connection is OK. Do nothing.\r
-\r
-                       *ServerResult = TRUE;\r
-\r
-               } else if (conncode == CURLE_SSL_CACERT || conncode == CURLE_SSL_CONNECT_ERROR){\r
-\r
-                       connssldata = curl_easy_init();\r
-\r
-                       // Retry but get the certificates without peer/host verification.\r
-\r
-                       curl_easy_setopt(connssldata, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(connssldata, CURLOPT_CERTINFO, 1);\r
-                       curl_easy_setopt(connssldata, CURLOPT_VERBOSE, 1L);\r
-                       curl_easy_setopt(connssldata, CURLOPT_ERRORBUFFER, curlerrbuffer);\r
-                       curl_easy_setopt(connssldata, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                       curl_easy_setopt(connssldata, CURLOPT_WRITEDATA, &PageData);\r
-                       curl_easy_setopt(connssldata, CURLOPT_WRITEHEADER, &PageHeader);\r
-                       curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYPEER, 0L);\r
-                       curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYHOST, 0L);\r
-\r
-                       CURLcode certfetchcode;\r
-\r
-                       certfetchcode = (curl_easy_perform(connssldata));\r
-\r
-                       VerifyCertCollection = BuildSSLCollection(connssldata);\r
-\r
-                       if (certfetchcode == CURLE_OK){\r
-                               \r
-                               curl_easy_getinfo(connssldata, CURLINFO_CERTINFO, &ptr.certdata);\r
-\r
-                               VerifyCertCollection = BuildSSLCollection(connssldata);\r
-\r
-                       } else {\r
-\r
-                               conncode = certfetchcode;\r
-\r
-                       }\r
-\r
-                       *ServerResult = FALSE;\r
-\r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                               curl_easy_strerror(conncode));\r
-\r
-                       ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));\r
-\r
-                       *ServerResult = FALSE;\r
-\r
-               }\r
-\r
-       }\r
-\r
-       curl_easy_cleanup(conn);\r
-\r
-       return conncode;\r
-\r
-}\r
-\r
 SSLCertCollection CardDAV::GetSSLVerifyResults(){\r
        return VerifyCertCollection;\r
 }\r
@@ -366,3445 +235,95 @@ void CardDAV::AllowSelfSignTest(bool AllowSelfSignIn){
        AllowSelfSign = AllowSelfSignIn;\r
 }\r
 \r
-bool CardDAV::Connect(){\r
-\r
-       PageData.Clear();\r
-       PageHeader.Clear();\r
-\r
-       SSLStatus = TRUE;\r
-       AuthPassed = TRUE;\r
-       AbortConnection = FALSE;\r
-\r
-       CURL *conn;\r
-       CURLcode conncode;\r
-       wxString ServerAddressURL;\r
-       wxString ServerAuth;\r
-       wxString ServerAddressSSL;\r
-       wxString ServerAddressNormal;   \r
-\r
-        conn = curl_easy_init();\r
-\r
-       struct CardDAVCURLPasser {\r
-       \r
-               CardDAV *Data;\r
-               bool HeaderMode = TRUE;\r
-       \r
-       } CardDAVHeader, CardDAVFooter;\r
-\r
-       CardDAVHeader.Data = this;\r
-       CardDAVHeader.HeaderMode = TRUE;\r
-       \r
-       CardDAVFooter.Data = this;\r
-       CardDAVFooter.HeaderMode = FALSE;\r
-\r
-       wxString Data1;\r
-       wxString Data2;\r
-       \r
-       ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
-       ServerAddressSSL = wxT("https://") + ServerAddressURL;\r
-       ServerAddressNormal = wxT("http://") + ServerAddressURL;\r
-       \r
-       ServerAuth = ServerUser + wxT(":") + ServerPass;\r
-       \r
-       // Try SSL first.\r
-\r
-\r
-       /*\r
-       char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];\r
-       //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());\r
-       strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));\r
-       \r
-       char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];\r
-       //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       \r
-       strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));\r
-\r
-       char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];\r
-       //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); \r
-       strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));\r
-       \r
-       */\r
-       \r
-       if (ServerSSL){\r
-\r
-               union {\r
-                       struct curl_slist       *certdata;\r
-                       struct curl_certinfo    *certinfo;\r
-               } ptr;\r
-\r
-               ptr.certdata = NULL;\r
-\r
-               // Setup two initial connections and attempt to get the certificate data.\r
-\r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);\r
-\r
-               conncode = (curl_easy_perform(conn));\r
-\r
-               // Check if the SSL certificate is valid or self-signed or some other\r
-               // error occured.\r
-\r
-               if (conncode == CURLE_OK){\r
-\r
-                       // Connection is OK. Do nothing.\r
-\r
-               } else if (conncode == CURLE_SSL_CACERT){\r
-\r
-                       // Post message saying SSL certificate is invalid. \r
-\r
-                       curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata);\r
-\r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                               curl_easy_strerror(conncode));\r
-\r
-                       ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));\r
-\r
-                       *ServerResult = FALSE;\r
-                       return FALSE;\r
-\r
-               }\r
-\r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);\r
-               \r
-               if (AllowSelfSign == TRUE){\r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L);\r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L);\r
-               }\r
-\r
-               conncode = (curl_easy_perform(conn));\r
-               \r
-               ptr.certdata = NULL;\r
-\r
-               curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata);\r
-               \r
-               if (conncode == CURLE_OK){\r
-\r
-                       // Process the server header response and look for\r
-                       // 'addressbook' within the DAV header.\r
-\r
-                       wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n"));\r
-                       wxString wxSHeaderLine;\r
-                       std::map<int, wxString> DAVHeaderLines;\r
-\r
-                       while (wxSHeaderLines.HasMoreTokens()){\r
-\r
-                               wxSHeaderLine = wxSHeaderLines.GetNextToken();\r
-\r
-                               if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){\r
-\r
-                                       // Look for address book in the line.\r
-\r
-                                       if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){\r
-\r
-                                               HasCalDAVSupport = TRUE;\r
-\r
-                                       }\r
-\r
-                               }\r
-\r
-                       }\r
-\r
-                       *ServerResult = TRUE;\r
-                       ValidResponse = TRUE;\r
-                       AuthPassed = TRUE;\r
-                       SSLStatus = TRUE;\r
-                       return TRUE;\r
-\r
-               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
-               \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-                               \r
-                       ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));\r
-\r
-                       *ServerResult = TRUE;\r
-                       ValidResponse = FALSE;\r
-                       AuthPassed = FALSE;\r
-                       SSLStatus = TRUE;\r
-                       return TRUE;\r
-               \r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-\r
-                       ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));\r
-\r
-                       *ServerResult = FALSE;\r
-                       return FALSE;                                   \r
-\r
-               }\r
+void CardDAV::GetSSLResults(){\r
 \r
-       } else {\r
        \r
-       // No SSL.\r
-               \r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);    \r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-\r
-               conncode = (curl_easy_perform(conn));\r
-\r
-               if (conncode == CURLE_OK){\r
-\r
-                       // Process the server header response and look for\r
-                       // 'addressbook' within the DAV header.\r
-                       \r
-                       wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n"));\r
-                       wxString wxSHeaderLine;\r
-                       std::map<int, wxString> DAVHeaderLines;\r
-                       \r
-                       while (wxSHeaderLines.HasMoreTokens()){\r
-                       \r
-                               wxSHeaderLine = wxSHeaderLines.GetNextToken();\r
-                               \r
-                               if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){\r
-                               \r
-                                       // Look for address book in the line.\r
-                                       \r
-                                       if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){\r
-                                       \r
-                                               HasCalDAVSupport = TRUE;\r
-                                       \r
-                                       }\r
-                               \r
-                               }\r
-                       \r
-                       }\r
-\r
-                       *ServerResult = TRUE;\r
-                       ValidResponse = TRUE;                   \r
-                       AuthPassed = TRUE;\r
-                       SSLStatus = FALSE;\r
-                       return TRUE;\r
 \r
-               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
-               \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-                                       \r
-                       *ServerResult = TRUE;\r
-                       ValidResponse = FALSE;\r
-                       AuthPassed = FALSE;\r
-                       SSLStatus = FALSE;\r
-                       return TRUE;\r
-               \r
-               } else {\r
+}\r
 \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-                               \r
-                       *ServerResult = FALSE;\r
-                       return FALSE;\r
+void CardDAV::SetServerFilename(wxString Filename){\r
 \r
-               }\r
-               \r
-               // TODO: Double check and make sure HTTP Authentication is possible.\r
-               \r
-       }               \r
-               \r
-       *ServerResult = TRUE;\r
-       return TRUE;    \r
+       ServerFilenameLocation = Filename;\r
 \r
 }\r
 \r
-void CardDAV::GetSSLResults(){\r
+wxString CardDAV::GetPageData()\r
+{\r
 \r
-       \r
+       return PageData;\r
 \r
 }\r
 \r
-void CardDAV::ProcessDataThread(){\r
+wxString CardDAV::ETagValueResult(){\r
 \r
-       PageData.Clear();\r
-       PageHeader.Clear();\r
+       return ETagResult;\r
 \r
-       SSLStatus = TRUE;\r
-       AuthPassed = TRUE;\r
-       AbortConnection = FALSE;\r
+}\r
 \r
-        CURL *conn;\r
-        CURLcode conncode;\r
-       wxString ServerAddressURL;\r
-       wxString ServerAuth;\r
-       wxString ServerAddressSSL;\r
-       wxString ServerAddressNormal;   \r
+void CardDAV::SetupData(wxString Method, wxString FilenameLocation, wxString UploadData){\r
 \r
-        conn = curl_easy_init();\r
-       \r
-       struct CardDAVCURLPasser {\r
-       \r
-               CardDAV *Data;\r
-               bool HeaderMode = TRUE;\r
-       \r
-       } CardDAVHeader, CardDAVFooter;\r
+       ServerMethod = Method;\r
+       ServerFilenameLocation = FilenameLocation;\r
+       ServerUploadData = UploadData;\r
 \r
-       CardDAVHeader.Data = this;\r
-       CardDAVHeader.HeaderMode = TRUE;\r
+       // Check if ServerFilenameLocation has a / at \r
+       // the start and if not then append it.\r
        \r
-       CardDAVFooter.Data = this;\r
-       CardDAVFooter.HeaderMode = FALSE;\r
-\r
-       wxString Data1;\r
-       wxString Data2;\r
+       if (ServerFilenameLocation.Left(1) != wxT("/")){\r
        \r
-       wxString ETag;\r
-       wxString ETagOriginal;\r
-       wxString ETagServer;\r
+               // Not there so insert.\r
                \r
-       ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation;\r
-       ServerAddressSSL = wxT("https://") + ServerAddressURL;\r
-       ServerAddressNormal = wxT("http://") + ServerAddressURL;\r
-       \r
-       ServerAuth = ServerUser + wxT(":") + ServerPass;\r
-       \r
-       // Try SSL first.\r
-\r
-\r
-       /*\r
-       char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];\r
-       //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());\r
-       strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));\r
+               ServerFilenameLocation = wxT("/") + ServerFilenameLocation;\r
        \r
-       char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];\r
-       //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       \r
-       strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));\r
+       }\r
 \r
-       char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];\r
-       //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); \r
-       strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));\r
-       \r
-       */\r
+}\r
 \r
-       //std::string WriteDataString = std::string(ServerUploadData.mb_str());\r
+void CardDAV::SetupVariables(std::map<int, int> *actlist, int actindex){\r
 \r
-       std::map<int,int>::iterator ActIter;\r
-       struct UploadDataStruc UploadData;\r
-       \r
-       \r
-       ActIter = ActivityListPtr->find((int)ItemIndex);\r
-       \r
-       // Update result flag.\r
+       ActivityListPtr = actlist;\r
+       ItemIndex = actindex;\r
 \r
-       ActIter->second = 1;\r
-       \r
-       // Setup the request mode if it is not empty.\r
-       \r
-       if (!ServerMethod.IsEmpty()){\r
-       \r
-               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, (const char*)ServerMethod.mb_str(wxConvUTF8));\r
+}\r
 \r
-       }\r
+wxString CardDAV::GetETagData(){\r
 \r
-       if (ServerSSL){\r
-\r
-               wxString ServerCertFilename;\r
-               bool MatchingCert = FALSE;\r
-\r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               \r
-               if (UploadMode == TRUE){\r
-                       \r
-                       UploadData.readptr = &ServerUploadData;\r
-                       UploadData.sizeleft = ServerUploadData.Len();\r
-                       curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
-                       curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
-                       curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
-               \r
-               }\r
+       return ETagData;\r
 \r
-               ServerCertFilename = GetAccountDir(ServerAccount, TRUE);\r
+}\r
 \r
-               if (wxFile::Exists(ServerCertFilename) == TRUE){\r
-               \r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);\r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);\r
-                       curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));\r
-               \r
-               }\r
+void CardDAV::SetUploadMode(bool IncMode){\r
 \r
-               //UploadData.readptr = &CardDAVDataQuery;\r
-               //UploadData.sizeleft = CardDAVDataQuery.Len();\r
-               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
-               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
-               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
-               \r
-               //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);\r
-               \r
-               claconncode = (curl_easy_perform(conn));\r
+       UploadMode = IncMode;\r
 \r
-               // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without\r
-               // the local certificate in use.\r
+}\r
 \r
-               if (claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
-                       \r
-                       curl_easy_cleanup(conn);\r
-                       conn = curl_easy_init();\r
-                       \r
-                       curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-                       curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                       curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-                       curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-                       curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-                       curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                       curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-                       curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                       curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-                       curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-                       curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-\r
-                       if (UploadMode == TRUE){\r
-\r
-                               UploadData.readptr = &ServerUploadData;\r
-                               UploadData.sizeleft = ServerUploadData.Len();\r
-                               curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
-                               curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
-                               curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
-               \r
-                       }\r
-                       \r
-                       claconncode = (curl_easy_perform(conn));\r
-                       \r
-                       // If claconncode is CURLE_OK then delete the certificate file as that\r
-                       // is no longer needed.\r
-                       \r
-                       if (claconncode == CURLE_OK){\r
-                       \r
-                               // Delete the certificate file.\r
-                               \r
-                               wxRemoveFile(ServerCertFilename);\r
-                       \r
-                       }\r
-               \r
-               }\r
+void CardDAV::SetEditMode(bool EditModeInc){\r
 \r
-               // Check if it fails with a CURLE_SSL_CACERT then compare\r
-               // the certificates as PEM files.\r
-               \r
-               if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){\r
-               \r
-                       //curl_easy_cleanup(conn);\r
-                       //conn = curl_easy_init();\r
-\r
-                       CURL *sslerrconn;\r
-                       sslerrconn = curl_easy_init();\r
-                       CURLcode sslerrconncode;\r
-\r
-                       //claconncode = (curl_easy_perform(conn));\r
-\r
-                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
-\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
-               \r
-                       wxString SSLLocalData;\r
-                       wxString SSLServerData;\r
-               \r
-                       sslerrconncode = (curl_easy_perform(sslerrconn));\r
-               \r
-                       SSLCertCol = BuildSSLCollection(sslerrconn);\r
-                       std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);\r
-                       std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));\r
-                       \r
-                       wxFFile SSLLocalFile;\r
-                       \r
-#if wxABI_VERSION < 20900\r
-                       SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));\r
-#else\r
-                       SSLLocalFile.Open(ServerCertFilename, wxT("r"));\r
-#endif \r
-       \r
-                       // Load the recovery database for tasks not done.\r
-       \r
-                       if (SSLLocalFile.IsOpened() == TRUE){\r
+       EditMode = EditModeInc;\r
 \r
-                       // Check if we are using wxWidgets version 2.8 or less and\r
-                       // execute the required command accordingly.\r
-       \r
-                               SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());\r
-               \r
-       \r
-                       }\r
-                       \r
-                       SSLServerData = SSLDataIter->second;\r
-                       \r
-                       if (SSLLocalData == SSLServerData){\r
-                       \r
-                               // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER\r
-                               // and CURLOPT_SSL_VERIFYHOST off.\r
-                       \r
-                               curl_easy_cleanup(conn);\r
-                               conn = curl_easy_init();\r
-                               \r
-                               PageData.clear();\r
-                               PageHeader.clear();\r
-                       \r
-                               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-                               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-                               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-                               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-                               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-                               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-                               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-                               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-                               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-                               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-\r
-                               if (UploadMode == TRUE){\r
-\r
-                                       UploadData.readptr = &ServerUploadData;\r
-                                       UploadData.sizeleft = ServerUploadData.Len();\r
-                                       curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
-                                       curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
-                                       curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
-               \r
-                               }\r
-                               \r
-                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);\r
-                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);\r
-                       \r
-                               claconncode = (curl_easy_perform(conn));\r
-                               \r
-                               MatchingCert = TRUE;\r
-                       \r
-                       }\r
-                       \r
-                       if (MatchingCert == FALSE){\r
-               \r
-                               claconncode = CURLE_SSL_CACERT;\r
-                               return;\r
-               \r
-                       }\r
-                       \r
-                       curl_easy_cleanup(sslerrconn);\r
-               \r
-               }\r
+}\r
 \r
-               // Sort out SSL error.\r
-               \r
-               // When SSL cert error occurs, connect again and fetch certificates.\r
-               // Display a message to the user explaining that an invalid\r
-               // certificate has been given and let the user decide what\r
-               // to do next.\r
+int CardDAV::GetResultCode(){\r
 \r
-               if (claconncode == CURLE_OK){\r
+       return (int)claconncode;\r
 \r
-               } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
-               \r
-                       CURL *sslerrconn;\r
-                       sslerrconn = curl_easy_init();\r
-                       CURLcode sslerrconncode;\r
-               \r
-                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
-               \r
-                       // Replace conn with sslerrconn!\r
-               \r
-                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
-               \r
-                       sslerrconncode = (curl_easy_perform(sslerrconn));\r
+}\r
 \r
-                       SSLCertCol = BuildSSLCollection(sslerrconn);\r
-                       SSLCertCol.SuccessCode = 1;\r
+int CardDAV::GetHTTPCode(){\r
 \r
-                       return;\r
-               \r
-               } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){\r
-               \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(claconncode));\r
-                       int http_code = 0;\r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
-                       fprintf(stderr, "Error code was: %d\n", http_code);\r
-                                       \r
-                       return;\r
-               \r
-               } else {\r
+       return HTTPErrorCode;\r
 \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(claconncode));\r
-                       int http_code = 0;\r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
-                       fprintf(stderr, "Error code was: %d\n", http_code);\r
+}\r
 \r
-                       return;\r
+wxString CardDAV::GetErrorBuffer(){\r
 \r
-               }\r
-\r
-       } else {\r
-       \r
-       // No SSL.\r
-               \r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               \r
-               if (UploadMode == TRUE){\r
-                       \r
-                       UploadData.readptr = &ServerUploadData;\r
-                       UploadData.sizeleft = ServerUploadData.Len();\r
-                       curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
-                       curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
-                       curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
-               \r
-               }\r
-               \r
-               conncode = (curl_easy_perform(conn));\r
-\r
-               if (conncode == CURLE_OK){\r
-\r
-                       // Process the server header response and look for\r
-                       // 'addressbook' within the DAV header.\r
-                       \r
-                       wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n"));\r
-                       wxString wxSHeaderLine;\r
-                       std::map<int, wxString> DAVHeaderLines;\r
-                       \r
-                       while (wxSHeaderLines.HasMoreTokens()){\r
-                       \r
-                               wxSHeaderLine = wxSHeaderLines.GetNextToken();\r
-                               \r
-                               if (wxSHeaderLine.Mid(0, 5) == wxT("ETag:")){\r
-                               \r
-                                       ETagData = wxSHeaderLine.Mid(5);\r
-                                       ETagData.Trim();\r
-                                       ETagData.Trim(FALSE);\r
-                                       \r
-                                       // Check for commas.\r
-                                       \r
-                                       if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){\r
-                                                       \r
-                                               ETagData.Remove(0, 1);\r
-                                               ETagData.RemoveLast();\r
-                                                       \r
-                                       }\r
-                               \r
-                               }\r
-                               \r
-                               if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){\r
-                               \r
-                                       // Look for address book in the line.\r
-                                       \r
-                                       if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){\r
-                                       \r
-                                               HasCalDAVSupport = TRUE;\r
-                                       \r
-                                       }\r
-                               \r
-                               }\r
-                       \r
-                       }\r
-                       \r
-                       // Get the ETag from the header.\r
-                       \r
-                       if (UploadMode == TRUE){\r
-               \r
-                               wxString PageHeaderLine;\r
-               \r
-                               wxStringTokenizer PageHeaderSplit(PageHeader, wxT("\r\n"));\r
-                               \r
-                               if (PageHeaderSplit.HasMoreTokens()){\r
-                               \r
-                                       PageHeaderLine = PageHeaderSplit.GetNextToken();\r
-                               \r
-                               }\r
-               \r
-                       }\r
-\r
-                       ActIter->second = 4;\r
-                       return;\r
-\r
-               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
-\r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);\r
-               \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-\r
-                       fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",\r
-                                       GetHTTPCode());\r
-\r
-                       ActIter->second = 2;\r
-                       return;\r
-               \r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-                               \r
-                       ActIter->second = 2;\r
-                       return;\r
-\r
-               }\r
-               \r
-       }\r
-       \r
-       /*\r
-       \r
-       }\r
-       \r
-       */\r
-       \r
-       // Connection was successful \r
-               /*      \r
-       \r
-       if (conn){\r
-               \r
-               wxString ServerAddressURL;\r
-               \r
-               // Try secure connection first.\r
-               \r
-               \r
-               \r
-\r
-               ServerAddressURL = wxT("http://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
-               \r
-               ServerAddressURL.Trim();\r
-               \r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressURL.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, NULL);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, NULL);\r
-                       \r
-\r
-               conncode = (curl_easy_perform(conn));\r
-\r
-               if (conncode == CURLE_OK){\r
-                       *ServerResult = TRUE;\r
-                       return TRUE;\r
-               \r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                               curl_easy_strerror(conncode));                  \r
-\r
-                       *ServerResult = FALSE;\r
-                       return FALSE;           \r
-               }\r
-\r
-               // Failed. So use unsecure connection.\r
-               UseSSL = FALSE;\r
-               \r
-               ServerAddress = wxT("http://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort);\r
-               \r
-               curl_easy_setopt(conn, CURLOPT_URL, ServerAddress.c_str());\r
-       \r
-               conncode = (curl_easy_perform(conn));           \r
-               \r
-               if (conncode != CURLE_OK){\r
-                       *ServerResult = FALSE;\r
-                       return FALSE;\r
-               } else {\r
-                       *ServerResult = TRUE;\r
-                       return TRUE;\r
-               }\r
-       \r
-       } else {\r
-       \r
-               *ServerResult = FALSE;\r
-               return FALSE;\r
-       \r
-       }\r
-       \r
-               */\r
-       \r
-       // Catch all.\r
-       \r
-       //ActIter->second = 1;\r
-       *ServerResult = TRUE;\r
-       return;\r
-\r
-}\r
-\r
-void CardDAV::ProcessData(){\r
-\r
-       std::thread ConnectThread(&CardDAV::ProcessDataThread, this);\r
-       ConnectThread.detach();\r
-\r
-}\r
-\r
-void CardDAV::SetServerFilename(wxString Filename){\r
-\r
-       ServerFilenameLocation = Filename;\r
-\r
-}\r
-\r
-void CardDAV::GetServerContactData()\r
-{\r
-\r
-       PageData.Clear();\r
-       PageHeader.Clear();\r
-\r
-       SSLStatus = TRUE;\r
-       AuthPassed = TRUE;\r
-       AbortConnection = FALSE;\r
-       \r
-       wxString ServerCertFilename;\r
-       bool MatchingCert = FALSE;\r
-\r
-        CURL *conn;\r
-        CURLcode conncode;\r
-       wxString ServerAddressURL;\r
-       wxString ServerAuth;\r
-       wxString ServerAddressSSL;\r
-       wxString ServerAddressNormal;   \r
-\r
-        conn = curl_easy_init();\r
-       \r
-       struct CardDAVCURLPasser {\r
-       \r
-               CardDAV *Data;\r
-               bool HeaderMode = TRUE;\r
-       \r
-       } CardDAVHeader, CardDAVFooter;\r
-\r
-       CardDAVHeader.Data = this;\r
-       CardDAVHeader.HeaderMode = TRUE;\r
-       \r
-       CardDAVFooter.Data = this;\r
-       CardDAVFooter.HeaderMode = FALSE;\r
-\r
-       wxString Data1;\r
-       wxString Data2;\r
-       \r
-       ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation;\r
-       ServerAddressSSL = wxT("https://") + ServerAddressURL;\r
-       ServerAddressNormal = wxT("http://") + ServerAddressURL;\r
-       \r
-       ServerAuth = ServerUser + wxT(":") + ServerPass;\r
-       \r
-       // Try SSL first.\r
-\r
-\r
-       /*\r
-       char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];\r
-       //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());\r
-       strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));\r
-       \r
-       char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];\r
-       //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       \r
-       strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));\r
-\r
-       char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];\r
-       //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); \r
-       strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));\r
-       \r
-       */\r
-\r
-       //std::string WriteDataString = std::string(ServerUploadData.mb_str());\r
-\r
-       std::map<int,int>::iterator ActIter;\r
-       struct UploadDataStruc UploadData;\r
-       \r
-       \r
-       ActIter = ActivityListPtr->find((int)ItemIndex);\r
-\r
-       //ActIter->second = 1;\r
-\r
-       /*wxString CardDAVDataQuery = wxT("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n");\r
-       CardDAVDataQuery.Append(wxT("<C:addressbook-multiget xmlns:D=\"DAV:\"\r\n"));\r
-       CardDAVDataQuery.Append(wxT("   xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\r\n"));\r
-       CardDAVDataQuery.Append(wxT("<D:prop><D:getetag/>\r\n"));\r
-       CardDAVDataQuery.Append(wxT("<C:address-data>\r\n"));\r
-       CardDAVDataQuery.Append(wxT("   <C:allprop/>\r\n"));\r
-       CardDAVDataQuery.Append(wxT("</C:address-data></D:prop>\r\n"));\r
-       CardDAVDataQuery.Append(wxT("</C:addressbook-multiget>"));*/\r
-\r
-       if (ServerSSL){\r
-\r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               \r
-               //UploadData.readptr = &CardDAVDataQuery;\r
-               //UploadData.sizeleft = CardDAVDataQuery.Len();\r
-               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
-               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
-               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
-\r
-               ServerCertFilename = GetAccountDir(ServerAccount, TRUE);\r
-\r
-               if (wxFile::Exists(ServerCertFilename) == TRUE){\r
-               \r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);\r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);\r
-                       curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));\r
-               \r
-               }\r
-\r
-               claconncode = (curl_easy_perform(conn));\r
-\r
-               // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without\r
-               // the local certificate in use.\r
-\r
-               if (claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
-                       \r
-                       curl_easy_cleanup(conn);\r
-                       conn = curl_easy_init();\r
-                       \r
-                       curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
-                       curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                       curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-                       curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-                       curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
-                       curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                       curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-                       curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                       curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               \r
-                       //UploadData.readptr = &CardDAVDataQuery;\r
-                       //UploadData.sizeleft = CardDAVDataQuery.Len();\r
-                       \r
-                       claconncode = (curl_easy_perform(conn));\r
-                       \r
-                       // If claconncode is CURLE_OK then delete the certificate file as that\r
-                       // is no longer needed.\r
-                       \r
-                       if (claconncode == CURLE_OK){\r
-                       \r
-                               // Delete the certificate file.\r
-                               \r
-                               wxRemoveFile(ServerCertFilename);\r
-                       \r
-                       }\r
-               \r
-               }\r
-\r
-               // Check if it fails with a CURLE_SSL_CACERT then compare\r
-               // the certificates as PEM files.\r
-               \r
-               if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){\r
-               \r
-                       //curl_easy_cleanup(conn);\r
-                       //conn = curl_easy_init();\r
-\r
-                       CURL *sslerrconn;\r
-                       sslerrconn = curl_easy_init();\r
-                       CURLcode sslerrconncode;\r
-\r
-                       //claconncode = (curl_easy_perform(conn));\r
-\r
-                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
-\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 1L);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);               \r
-                       curl_easy_setopt(sslerrconn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
-               \r
-                       //UploadData.readptr = &CardDAVDataQuery;\r
-                       //UploadData.sizeleft = CardDAVDataQuery.Len();\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYHOST, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
-               \r
-                       wxString SSLLocalData;\r
-                       wxString SSLServerData;\r
-               \r
-                       sslerrconncode = (curl_easy_perform(sslerrconn));\r
-               \r
-                       SSLCertCol = BuildSSLCollection(sslerrconn);\r
-                       std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);\r
-                       std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));\r
-                       \r
-                       wxFFile SSLLocalFile;\r
-                       \r
-#if wxABI_VERSION < 20900\r
-                       SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));\r
-#else\r
-                       SSLLocalFile.Open(ServerCertFilename, wxT("r"));\r
-#endif \r
-       \r
-                       // Load the recovery database for tasks not done.\r
-       \r
-                       if (SSLLocalFile.IsOpened() == TRUE){\r
-       \r
-                               SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());\r
-               \r
-       \r
-                       }\r
-                       \r
-                       SSLServerData = SSLDataIter->second;\r
-                       \r
-                       if (SSLLocalData == SSLServerData){\r
-                       \r
-                               // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER\r
-                               // and CURLOPT_SSL_VERIFYHOST off.\r
-                       \r
-                               curl_easy_cleanup(conn);\r
-                               conn = curl_easy_init();\r
-                               \r
-                               PageData.clear();\r
-                               PageHeader.clear();\r
-                       \r
-                               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-                               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
-                               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-                               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-                               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
-                               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-                               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-                               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               \r
-                               //UploadData.readptr = &CardDAVDataQuery;\r
-                               //UploadData.sizeleft = CardDAVDataQuery.Len();\r
-                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);\r
-                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);\r
-                                                       \r
-                               claconncode = (curl_easy_perform(conn));\r
-                               \r
-                               MatchingCert = TRUE;\r
-                       \r
-                       }\r
-                       \r
-                       if (MatchingCert == FALSE){\r
-               \r
-                               claconncode = CURLE_SSL_CACERT;\r
-                               return;\r
-               \r
-                       }\r
-                       \r
-                       curl_easy_cleanup(sslerrconn);\r
-               \r
-               }\r
-               \r
-               // Sort out SSL error.\r
-               \r
-               // When SSL cert error occurs, connect again and fetch certificates.\r
-               // Display a message to the user explaining that an invalid\r
-               // certificate has been given and let the user decide what\r
-               // to do next.\r
-\r
-               if (claconncode == CURLE_OK){\r
-\r
-               } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
-               \r
-                       CURL *sslerrconn;\r
-                       sslerrconn = curl_easy_init();\r
-                       CURLcode sslerrconncode;\r
-               \r
-                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
-               \r
-                       // Replace conn with sslerrconn!\r
-               \r
-                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
-                                       \r
-                       sslerrconncode = (curl_easy_perform(sslerrconn));\r
-\r
-                       SSLCertCol = BuildSSLCollection(sslerrconn);\r
-                       SSLCertCol.SuccessCode = 1;\r
-\r
-                       return;\r
-               \r
-               } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){\r
-               \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(claconncode));\r
-                       int http_code = 0;\r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
-                       fprintf(stderr, "Error code was: %d\n", http_code);\r
-                                       \r
-                       return;\r
-               \r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(claconncode));\r
-                       int http_code = 0;\r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
-                       fprintf(stderr, "Error code was: %d\n", http_code);\r
-\r
-                       return;\r
-\r
-               }\r
-       } else {\r
-       \r
-               // No SSL.\r
-               \r
-               wxString EmptyString;\r
-               \r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               \r
-               //UploadData.readptr = &CardDAVDataQuery;\r
-               //UploadData.sizeleft = CardDAVDataQuery.Len();\r
-               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
-               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
-               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
-\r
-               //UploadData.readptr = &CardDAVDataQuery;\r
-               //UploadData.sizeleft = CardDAVDataQuery.Len();\r
-               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
-               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
-               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
-               \r
-               //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);     \r
-               \r
-               PageData.Clear();\r
-               PageHeader.Clear();\r
-               \r
-               conncode = (curl_easy_perform(conn));\r
-\r
-               if (conncode == CURLE_OK){\r
-\r
-               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
-               \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-                                       \r
-                       fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",\r
-                                       GetHTTPCode());\r
-                                       \r
-                       return;\r
-               \r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-                               \r
-                       return;\r
-\r
-               }\r
-               \r
-       }\r
-       \r
-       return;\r
-\r
-}\r
-\r
-wxString CardDAV::GetPageData()\r
-{\r
-\r
-       return PageData;\r
-\r
-}\r
-\r
-void CardDAV::GetServerETagValueThread()\r
-{\r
-\r
-       PageData.Clear();\r
-       PageHeader.Clear();\r
-\r
-       SSLStatus = TRUE;\r
-       AuthPassed = TRUE;\r
-       AbortConnection = FALSE;\r
-       \r
-       bool FilenameIsDirectory = FALSE;\r
-        CURL *conn;\r
-        CURLcode conncode;\r
-       wxString ServerAddressURL;\r
-       wxString ServerAuth;\r
-       wxString ServerAddressSSL;\r
-       wxString ServerAddressNormal;   \r
-\r
-        conn = curl_easy_init();\r
-       \r
-       struct CardDAVCURLPasser {\r
-       \r
-               CardDAV *Data;\r
-               bool HeaderMode = TRUE;\r
-       \r
-       } CardDAVHeader, CardDAVFooter;\r
-\r
-       CardDAVHeader.Data = this;\r
-       CardDAVHeader.HeaderMode = TRUE;\r
-       \r
-       CardDAVFooter.Data = this;\r
-       CardDAVFooter.HeaderMode = FALSE;\r
-\r
-       wxString Data1;\r
-       wxString Data2;\r
-       \r
-       ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + ServerFilenameLocation;\r
-       ServerAddressSSL = wxT("https://") + ServerAddressURL;\r
-       ServerAddressNormal = wxT("http://") + ServerAddressURL;\r
-       \r
-       ServerAuth = ServerUser + wxT(":") + ServerPass;\r
-       \r
-       // Workout if path is directory or filename.\r
-       \r
-       /*if (ServerAddress){\r
-               FilenameIsDirectory = TRUE;\r
-       } else {\r
-               FilenameIsDirectory = FALSE;\r
-       }*/\r
-       \r
-       // Try SSL first.\r
-\r
-\r
-       /*\r
-       char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];\r
-       //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());\r
-       strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));\r
-       \r
-       char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];\r
-       //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       \r
-       strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));\r
-\r
-       char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];\r
-       //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); \r
-       strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));\r
-       \r
-       */\r
-\r
-       //std::string WriteDataString = std::string(ServerUploadData.mb_str());\r
-\r
-       std::map<int,int>::iterator ActIter;\r
-       struct UploadDataStruc UploadData;\r
-       \r
-       \r
-       ActIter = ActivityListPtr->find((int)ItemIndex);\r
-       \r
-       static const char* query =\r
-       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"\r
-       "<C:addressbook-query xmlns:D=\"DAV:\""\r
-       "       xmlns:C=\"urn:ietf:params:xml:ns:carddav\">"\r
-       "<D:prop><D:getetag/>"\r
-       //"<C:address-data>"\r
-       //"     <C:allprop/>"\r
-       //"</C:address-data></D:prop>"\r
-       "</D:prop>"\r
-       "<C:filter/>"\r
-       "</C:addressbook-query>";\r
-\r
-       if (ServerSSL){\r
-\r
-               wxString ServerCertFilename;\r
-               bool MatchingCert = FALSE;\r
-\r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-\r
-               //UploadData.readptr = &CardDAVDataQuery;\r
-               //UploadData.sizeleft = CardDAVDataQuery.Len();\r
-               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
-               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
-               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
-               \r
-               //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));\r
-\r
-               ServerCertFilename = GetAccountDir(ServerAccount, TRUE);\r
-\r
-               if (wxFile::Exists(ServerCertFilename) == TRUE){\r
-               \r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);\r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);\r
-                       curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));\r
-               \r
-               }\r
-\r
-               claconncode = (curl_easy_perform(conn));\r
-\r
-               // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without\r
-               // the local certificate in use.\r
-\r
-               if (claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
-                       \r
-                       curl_easy_cleanup(conn);\r
-                       conn = curl_easy_init();\r
-                       \r
-                       curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-                       curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                       curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-                       curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-                       curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-                       curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                       curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-                       curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                       curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-                       curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-                       curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
-                       curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-                       curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
-                       curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));\r
-                       \r
-                       claconncode = (curl_easy_perform(conn));\r
-                       \r
-                       // If claconncode is CURLE_OK then delete the certificate file as that\r
-                       // is no longer needed.\r
-                       \r
-                       if (claconncode == CURLE_OK){\r
-                       \r
-                               // Delete the certificate file.\r
-                               \r
-                               wxRemoveFile(ServerCertFilename);\r
-                       \r
-                       }\r
-               \r
-               }\r
-\r
-               // Check if it fails with a CURLE_SSL_CACERT then compare\r
-               // the certificates as PEM files.\r
-               \r
-               if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){\r
-               \r
-                       //curl_easy_cleanup(conn);\r
-                       //conn = curl_easy_init();\r
-\r
-                       CURL *sslerrconn;\r
-                       sslerrconn = curl_easy_init();\r
-                       CURLcode sslerrconncode;\r
-\r
-                       //claconncode = (curl_easy_perform(conn));\r
-\r
-                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
-\r
-                       PageData.clear();\r
-                       PageHeader.clear();\r
-\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 1);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYHOST, 2);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));\r
-               \r
-                       wxString SSLLocalData;\r
-                       wxString SSLServerData;\r
-               \r
-                       sslerrconncode = (curl_easy_perform(sslerrconn));\r
-               \r
-                       SSLCertCol = BuildSSLCollection(sslerrconn);\r
-                       std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);\r
-                       std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));\r
-                       \r
-                       wxFFile SSLLocalFile;\r
-                       \r
-#if wxABI_VERSION < 20900\r
-                       SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));\r
-#else\r
-                       SSLLocalFile.Open(ServerCertFilename, wxT("r"));\r
-#endif \r
-\r
-                       // Load the recovery database for tasks not done.\r
-       \r
-                       if (SSLLocalFile.IsOpened() == TRUE){\r
-\r
-                       // Check if we are using wxWidgets version 2.8 or less and\r
-                       // execute the required command accordingly.\r
-       \r
-                               SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());\r
-               \r
-       \r
-                       }\r
-                       \r
-                       SSLServerData = SSLDataIter->second;\r
-                       \r
-                       if (SSLLocalData == SSLServerData){\r
-                       \r
-                               // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER\r
-                               // and CURLOPT_SSL_VERIFYHOST off.\r
-                       \r
-                               curl_easy_cleanup(conn);\r
-                               conn = curl_easy_init();\r
-                               \r
-                               PageData.clear();\r
-                               PageHeader.clear();\r
-                       \r
-                               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-                               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-                               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-                               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-                               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-                               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-                               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-                               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-                               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-                               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
-                               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-                               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
-                               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));\r
-                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);\r
-                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);              \r
-                       \r
-                               claconncode = (curl_easy_perform(conn));\r
-                               \r
-                               MatchingCert = TRUE;\r
-                       \r
-                       }\r
-                       \r
-                       if (MatchingCert == FALSE){\r
-               \r
-                               claconncode = CURLE_SSL_CACERT;\r
-                               return;\r
-               \r
-                       }\r
-                       \r
-                       curl_easy_cleanup(sslerrconn);\r
-               \r
-               }\r
-\r
-               // Sort out SSL error.\r
-               \r
-               // When SSL cert error occurs, connect again and fetch certificates.\r
-               // Display a message to the user explaining that an invalid\r
-               // certificate has been given and let the user decide what\r
-               // to do next.\r
-\r
-               if (claconncode == CURLE_OK){\r
-\r
-               } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
-               \r
-                       CURL *sslerrconn;\r
-                       sslerrconn = curl_easy_init();\r
-                       CURLcode sslerrconncode;\r
-               \r
-                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
-               \r
-                       // Replace conn with sslerrconn!\r
-               \r
-                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
-                                       \r
-                       sslerrconncode = (curl_easy_perform(sslerrconn));\r
-\r
-                       SSLCertCol = BuildSSLCollection(sslerrconn);\r
-                       SSLCertCol.SuccessCode = 1;\r
-\r
-                       curl_easy_cleanup(conn);\r
-                       curl_easy_cleanup(sslerrconn);\r
-\r
-                       return;\r
-               \r
-               } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){\r
-               \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(claconncode));\r
-                       int http_code = 0;\r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
-                       fprintf(stderr, "Error code was: %d\n", http_code);\r
-\r
-                       curl_easy_cleanup(conn);\r
-                                       \r
-                       return;\r
-               \r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(claconncode));\r
-                       int http_code = 0;\r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
-                       fprintf(stderr, "Error code was: %d\n", http_code);\r
-\r
-                       curl_easy_cleanup(conn);\r
-\r
-                       return;\r
-\r
-               }\r
-\r
-       } else {\r
-       \r
-               // No SSL.\r
-       \r
-               wxString EmptyString;\r
-               \r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-\r
-               //UploadData.readptr = &CardDAVDataQuery;\r
-               //UploadData.sizeleft = CardDAVDataQuery.Len();\r
-               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
-               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
-               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
-               \r
-               //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));           \r
-               \r
-               PageData.Clear();\r
-               PageHeader.Clear();\r
-               \r
-               conncode = (curl_easy_perform(conn));\r
-\r
-               if (conncode == CURLE_OK){\r
-\r
-               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
-               \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-                               \r
-                       return;\r
-               \r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-                               \r
-                       return;\r
-\r
-               }\r
-               \r
-       }\r
-       \r
-       xmlDocPtr xmlCardDAVDoc;\r
-\r
-       xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);\r
-\r
-       xmlNodePtr nodeLevel1;\r
-       xmlNodePtr nodeLevel2;\r
-       xmlNodePtr nodeLevel3;\r
-       xmlNodePtr nodeLevel4;\r
-       xmlNodePtr nodeLevel5;\r
-       xmlNodePtr nodeLevel6;\r
-\r
-       std::map<wxString,wxString> xmlDataMap;\r
-\r
-       wxString DataFilename;\r
-       wxString ETagData;\r
-\r
-       std::string xmlStringSafe;\r
-\r
-       // Tranverse through the catacombs of the response to get our ETag for the file.\r
-\r
-       for (nodeLevel1 = xmlCardDAVDoc->children;\r
-               nodeLevel1 != NULL;\r
-               nodeLevel1 = nodeLevel1->next)\r
-       {\r
-\r
-               bool HREFFound = FALSE;\r
-               bool ETagFound = FALSE;\r
-\r
-               for (nodeLevel2 = nodeLevel1->children;\r
-                       nodeLevel2 != NULL;\r
-                       nodeLevel2 = nodeLevel2->next)\r
-               {\r
-\r
-                       for (nodeLevel3 = nodeLevel2->children;\r
-                       nodeLevel3 != NULL;\r
-                       nodeLevel3 = nodeLevel3->next)\r
-                       {\r
-\r
-                               if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||\r
-                               !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||\r
-                               !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")\r
-                               ){\r
-\r
-                                       // Get the filename.\r
-                                       \r
-                                       for (nodeLevel4 = nodeLevel3->children;\r
-                                       nodeLevel4 != NULL;\r
-                                       nodeLevel4 = nodeLevel4->next)\r
-                                       {\r
-                                       \r
-                                               if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||\r
-                                               !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||\r
-                                               !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")\r
-                                               ){\r
-\r
-                                                       DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);\r
-                                                       wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));\r
-                                               \r
-                                                       while (wSTDFilename.HasMoreTokens()){\r
-                                                       \r
-                                                               DataFilename = wSTDFilename.GetNextToken();\r
-                                                       \r
-                                                       }\r
-                                                       \r
-                                                       HREFFound = TRUE;\r
-                                               \r
-                                               }\r
-                                               \r
-       \r
-                                       \r
-                                       }\r
-\r
-                               } else {\r
-\r
-                                       for (nodeLevel4 = nodeLevel3->children;\r
-                                       nodeLevel4 != NULL;\r
-                                       nodeLevel4 = nodeLevel4->next)\r
-                                       {\r
-                                                       \r
-                                                       for (nodeLevel5 = nodeLevel4->children;\r
-                                                       nodeLevel5 != NULL;\r
-                                                       nodeLevel5 = nodeLevel5->next)\r
-                                                       {\r
-\r
-                                                               if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||\r
-                                                               !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||\r
-                                                               !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")\r
-                                                               ){\r
-\r
-                                                                       for (nodeLevel6 = nodeLevel5->children;\r
-                                                                       nodeLevel6 != NULL;\r
-                                                                       nodeLevel6 = nodeLevel6->next)\r
-                                                                       {\r
-                                                       \r
-                                                                               // Strip the quotes from the ETag.\r
-                                                       \r
-                                                                               ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);\r
-                                                                               if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){\r
-                                                       \r
-                                                                                       ETagData.Remove(0, 1);\r
-                                                                                       ETagData.RemoveLast();\r
-                                                       \r
-                                                                               }\r
-                                                                       \r
-                                                                               ETagFound = TRUE;\r
-\r
-                                                                       }\r
-                                                                       \r
-                                                               }\r
-\r
-                                                       }       \r
-\r
-                                       }\r
-\r
-                               }\r
-\r
-                       }\r
-\r
-               }\r
-               \r
-               if (HREFFound == TRUE && ETagFound == TRUE){\r
-                               \r
-                       // Add to the map data.\r
-                                       \r
-                       xmlDataMap.insert(std::make_pair(DataFilename, ETagData));\r
-                               \r
-                       HREFFound = FALSE;\r
-                       ETagFound = FALSE;\r
-                               \r
-               }\r
-\r
-\r
-       }\r
-\r
-       xmlFreeDoc(xmlCardDAVDoc);\r
-\r
-       // Get the first result.\r
-\r
-       for (std::map<wxString,wxString>::iterator iter = xmlDataMap.begin(); \r
-               iter != xmlDataMap.end(); ++iter){\r
-       \r
-               ETagResult = iter->second;\r
-               break;\r
-               \r
-       }\r
-       \r
-       if (ETagResult.IsEmpty()){\r
-       \r
-               return;\r
-       \r
-       }\r
-       \r
-       return;\r
-       \r
-}\r
-\r
-wxString CardDAV::ETagValueResult(){\r
-\r
-       return ETagResult;\r
-\r
-}\r
-\r
-void CardDAV::GetServerETagValue(){\r
-\r
-       std::thread ConnectThread(&CardDAV::GetServerETagValueThread, this);\r
-       ConnectThread.detach();\r
-\r
-}\r
-\r
-void CardDAV::SetupData(wxString Method, wxString FilenameLocation, wxString UploadData){\r
-\r
-       ServerMethod = Method;\r
-       ServerFilenameLocation = FilenameLocation;\r
-       ServerUploadData = UploadData;\r
-\r
-       // Check if ServerFilenameLocation has a / at \r
-       // the start and if not then append it.\r
-       \r
-       if (ServerFilenameLocation.Left(1) != wxT("/")){\r
-       \r
-               // Not there so insert.\r
-               \r
-               ServerFilenameLocation = wxT("/") + ServerFilenameLocation;\r
-       \r
-       }\r
-\r
-}\r
-\r
-void CardDAV::SetupVariables(std::map<int, int> *actlist, int actindex){\r
-\r
-       ActivityListPtr = actlist;\r
-       ItemIndex = actindex;\r
-\r
-}\r
-\r
-wxString CardDAV::GetETagData(){\r
-\r
-       return ETagData;\r
-\r
-}\r
-\r
-void CardDAV::SetUploadMode(bool IncMode){\r
-\r
-       UploadMode = IncMode;\r
-\r
-}\r
-\r
-void CardDAV::SetEditMode(bool EditModeInc){\r
-\r
-       EditMode = EditModeInc;\r
-\r
-}\r
-\r
-ContactListData CardDAV::GetContactList(wxString SyncTokenInc){\r
-\r
-       ContactListData ContactListFinal;\r
-       std::map<wxString,FileSyncData> ContactList;\r
-       \r
-       PageData.Clear();\r
-       PageHeader.Clear();\r
-\r
-       SSLStatus = TRUE;\r
-       AuthPassed = TRUE;\r
-       AbortConnection = FALSE;\r
-\r
-       CURL *conn;\r
-       wxString ServerAddressURL;\r
-       wxString ServerAuth;\r
-       wxString ServerAddressSSL;\r
-       wxString ServerAddressNormal;\r
-\r
-       conn = curl_easy_init();\r
-       \r
-       struct CardDAVCURLPasser {\r
-       \r
-               CardDAV *Data;\r
-               bool HeaderMode = TRUE;\r
-       \r
-       } CardDAVHeader, CardDAVFooter;\r
-\r
-       CardDAVHeader.Data = this;\r
-       CardDAVHeader.HeaderMode = TRUE;\r
-       \r
-       CardDAVFooter.Data = this;\r
-       CardDAVFooter.HeaderMode = FALSE;\r
-\r
-       wxString Data1;\r
-       wxString Data2;\r
-       \r
-       ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + wxT("/");\r
-       ServerAddressSSL = wxT("https://") + ServerAddressURL;\r
-       ServerAddressNormal = wxT("http://") + ServerAddressURL;\r
-       \r
-       ServerAuth = ServerUser + wxT(":") + ServerPass;\r
-       \r
-       // Load the sync token file (if it exists).\r
-       \r
-       wxCharBuffer SyncDataBuffer;\r
-       wxString SyncData;\r
-       \r
-       SyncData.Clear();\r
-       \r
-       SyncTokenInc.Trim();\r
-       \r
-       if (!SyncTokenInc.IsEmpty()){\r
-               \r
-               SyncData = wxT("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");\r
-               SyncData.Append(wxT("<D:sync-collection xmlns:D=\"DAV:\"\n"));\r
-               SyncData.Append(wxT(" xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"));\r
-               SyncData.Append(wxT("<D:sync-token>"));\r
-               //SyncData.Trim();\r
-               //SyncData.Append(wxT("data:,00378c55-1f44-44a2-a255-84f6560b5cac_580"));\r
-               SyncData.Append(SyncTokenInc);\r
-               //SyncData.Trim();\r
-               SyncData.Append(wxT("</D:sync-token>\n"));\r
-               SyncData.Append(wxT("<D:sync-level>1</D:sync-level>\n"));\r
-               SyncData.Append(wxT("<D:prop>\n"));\r
-               SyncData.Append(wxT("   <D:getetag/>\n"));\r
-               SyncData.Append(wxT("</D:prop>\n"));\r
-               SyncData.Append(wxT("</D:sync-collection>"));\r
-               \r
-               SyncDataBuffer = SyncData.ToUTF8();\r
-       \r
-       } else {\r
-               \r
-               SyncData = wxT("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");\r
-               SyncData.Append(wxT("<D:sync-collection xmlns:D=\"DAV:\""));\r
-               SyncData.Append(wxT(" xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"));\r
-               SyncData.Append(wxT("<D:sync-token/>\n"));\r
-               SyncData.Append(wxT("<D:sync-level>1</D:sync-level>\n"));\r
-               SyncData.Append(wxT("<D:prop>\n"));\r
-               SyncData.Append(wxT("   <D:getetag/>\n"));\r
-               SyncData.Append(wxT("</D:prop>\n"));\r
-               SyncData.Append(wxT("</D:sync-collection>\n"));\r
-               \r
-               SyncDataBuffer = SyncData.ToUTF8();\r
-\r
-       }\r
-       \r
-       //static const char* query = SyncData.mb_str();\r
-       \r
-       /*char *query = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\\r
-               <D:sync-collection xmlns:D=\"DAV:\"\n\\r
-                xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n\\r
-               <D:sync-token>data:,00378c55-1f44-44a2-a255-84f6560b5cac_580</D:sync-token>\n\\r
-               <D:sync-level>1</D:sync-level>\n\\r
-               <D:prop>\n\\r
-                       <D:getetag/>\n\\r
-               </D:prop>\n\\r
-       </D:sync-collection>\n";*/\r
-       const char* query = SyncDataBuffer.data();\r
-       \r
-       // Try SSL first.\r
-\r
-       std::map<int,int>::iterator ActIter;\r
-       struct UploadDataStruc UploadData;\r
-       \r
-       ActIter = ActivityListPtr->find((int)ItemIndex);\r
-\r
-       curl_slist *slist = NULL;       \r
-\r
-       slist = curl_slist_append(slist, "Depth: 1");\r
-\r
-       if (ServerSSL){\r
-\r
-               wxString ServerCertFilename;\r
-               bool MatchingCert = FALSE;\r
-\r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);\r
-               curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);\r
-\r
-               ServerCertFilename = GetAccountDir(ServerAccount, TRUE);\r
-\r
-               if (wxFile::Exists(ServerCertFilename) == TRUE){\r
-               \r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);\r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);\r
-                       curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));\r
-               \r
-               }\r
-\r
-               //UploadData.readptr = &CardDAVDataQuery;\r
-               //UploadData.sizeleft = CardDAVDataQuery.Len();\r
-               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
-               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
-               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
-               \r
-               //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));\r
-\r
-               claconncode = (curl_easy_perform(conn));\r
-\r
-               // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without\r
-               // the local certificate in use.\r
-\r
-               if (claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
-                       \r
-                       curl_easy_cleanup(conn);\r
-                       conn = curl_easy_init();\r
-                       \r
-                       curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-                       curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);\r
-                       curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-                       curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-                       curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-                       curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                       curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-                       curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                       curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-                       curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-                       curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
-                       curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-                       curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);\r
-                       curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);\r
-                       curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
-                       curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));\r
-                       \r
-                       claconncode = (curl_easy_perform(conn));\r
-                       \r
-                       // If claconncode is CURLE_OK then delete the certificate file as that\r
-                       // is no longer needed.\r
-                       \r
-                       if (claconncode == CURLE_OK){\r
-                       \r
-                               // Delete the certificate file.\r
-                               \r
-                               wxRemoveFile(ServerCertFilename);\r
-                       \r
-                       }\r
-               \r
-               }\r
-\r
-               // Check if it fails with a CURLE_SSL_CACERT then compare\r
-               // the certificates as PEM files.\r
-               \r
-               if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){\r
-               \r
-                       //curl_easy_cleanup(conn);\r
-                       //conn = curl_easy_init();\r
-\r
-                       CURL *sslerrconn;\r
-                       sslerrconn = curl_easy_init();\r
-                       CURLcode sslerrconncode;\r
-\r
-                       //claconncode = (curl_easy_perform(conn));\r
-\r
-                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
-\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
-               \r
-                       wxString SSLLocalData;\r
-                       wxString SSLServerData;\r
-               \r
-                       sslerrconncode = (curl_easy_perform(sslerrconn));\r
-               \r
-                       SSLCertCol = BuildSSLCollection(sslerrconn);\r
-                       std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);\r
-                       std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));\r
-                       \r
-                       wxFFile SSLLocalFile;\r
-                       \r
-#if wxABI_VERSION < 20900\r
-                       SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));\r
-#else\r
-                       SSLLocalFile.Open(ServerCertFilename, wxT("r"));\r
-#endif \r
-       \r
-                       // Load the recovery database for tasks not done.\r
-       \r
-                       if (SSLLocalFile.IsOpened() == TRUE){\r
-\r
-                       // Check if we are using wxWidgets version 2.8 or less and\r
-                       // execute the required command accordingly.\r
-       \r
-                               SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());\r
-               \r
-       \r
-                       }\r
-                       \r
-                       SSLServerData = SSLDataIter->second;\r
-                       \r
-                       if (SSLLocalData == SSLServerData){\r
-                       \r
-                               // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER\r
-                               // and CURLOPT_SSL_VERIFYHOST off.\r
-                       \r
-                               curl_easy_cleanup(conn);\r
-                               conn = curl_easy_init();\r
-                               \r
-                               PageHeader.clear();\r
-                               PageData.clear();\r
-                               \r
-                               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));\r
-                               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-                               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-                               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-                               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-                               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-                               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-                               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-                               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-                               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
-                               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-                               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);\r
-                               curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);\r
-                               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
-                               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));\r
-                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);\r
-                               curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);\r
-                       \r
-                               claconncode = (curl_easy_perform(conn));\r
-                               \r
-                               MatchingCert = TRUE;\r
-                       \r
-                       }\r
-                       \r
-                       if (MatchingCert == FALSE){\r
-               \r
-                               claconncode = CURLE_SSL_CACERT;\r
-                               return ContactListFinal;\r
-               \r
-                       }\r
-                       \r
-                       curl_easy_cleanup(sslerrconn);\r
-               \r
-               }\r
-\r
-               // Sort out SSL error.\r
-               \r
-               // When SSL cert error occurs, connect again and fetch certificates.\r
-               // Display a message to the user explaining that an invalid\r
-               // certificate has been given and let the user decide what\r
-               // to do next.\r
-\r
-               if (claconncode == CURLE_OK){\r
-\r
-               } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){\r
-               \r
-                       CURL *sslerrconn;\r
-                       sslerrconn = curl_easy_init();\r
-                       CURLcode sslerrconncode;\r
-               \r
-                       wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
-               \r
-                       // Replace conn with sslerrconn!\r
-               \r
-                       curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);\r
-                       curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);\r
-               \r
-                       sslerrconncode = (curl_easy_perform(sslerrconn));\r
-\r
-                       SSLCertCol = BuildSSLCollection(sslerrconn);\r
-                       SSLCertCol.SuccessCode = 1;\r
-\r
-                       return ContactListFinal;\r
-               \r
-               } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){\r
-               \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(claconncode));\r
-                       int http_code = 0;\r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
-                       fprintf(stderr, "Error code was: %d\n", http_code);\r
-                                       \r
-                       return ContactListFinal;\r
-               \r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(claconncode));\r
-                       int http_code = 0;\r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
-                       fprintf(stderr, "Error code was: %d\n", http_code);\r
-\r
-                       return ContactListFinal;\r
-\r
-               }\r
-\r
-               SSLCertCol = BuildSSLCollection(conn);\r
-\r
-       } else {\r
-       \r
-       // No SSL.\r
-               \r
-               wxString EmptyString;\r
-               \r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);\r
-\r
-               //UploadData.readptr = &CardDAVDataQuery;\r
-               //UploadData.sizeleft = CardDAVDataQuery.Len();\r
-               //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);\r
-               //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);\r
-               //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);\r
-               \r
-               //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));           \r
-               \r
-               PageData.Clear();\r
-               PageHeader.Clear();\r
-               \r
-               claconncode = (curl_easy_perform(conn));\r
-\r
-               if (claconncode == CURLE_OK){\r
-\r
-\r
-\r
-               } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){\r
-               \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(claconncode));\r
-                       int http_code = 0;\r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
-                       fprintf(stderr, "Error code was: %i\n", http_code);\r
-                                       \r
-                       return ContactListFinal;\r
-                       \r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(claconncode));\r
-                       int http_code = 0;\r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);\r
-                       fprintf(stderr, "Error code was: %i\n", http_code);\r
-                               \r
-                       return ContactListFinal;\r
-\r
-               }\r
-               \r
-       }\r
-\r
-       xmlDocPtr xmlCardDAVDoc;\r
-       xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);\r
-\r
-       xmlNodePtr nodeLevel1;\r
-       xmlNodePtr nodeLevel2;\r
-       xmlNodePtr nodeLevel3;\r
-       xmlNodePtr nodeLevel4;\r
-       xmlNodePtr nodeLevel5;\r
-       xmlNodePtr nodeLevel6;\r
-       \r
-       xmlNodePtr nodeStatusLv1;\r
-       xmlNodePtr nodeStatusLv2;\r
-\r
-       std::map<wxString,wxString> xmlDataMap;\r
-       std::map<wxString,wxString> ServerETagData;\r
-\r
-       wxString DataFilename;\r
-       wxString DataSyncToken;\r
-       int DataFileStatus;\r
-       wxString ETagData;\r
-       bool SyncTokenFound = FALSE;\r
-\r
-       std::string xmlStringSafe;\r
-\r
-       // Tranverse through the catacombs of the response to get our ETag for the file and\r
-       // the server syncronisation token.\r
-\r
-       // Start by getting all the server ETag data.\r
-\r
-       for (nodeLevel1 = xmlCardDAVDoc->children;\r
-               nodeLevel1 != NULL;\r
-               nodeLevel1 = nodeLevel1->next)\r
-       {\r
-\r
-               for (nodeLevel2 = nodeLevel1->children;\r
-                       nodeLevel2 != NULL;\r
-                       nodeLevel2 = nodeLevel2->next)\r
-               {\r
-\r
-                       for (nodeLevel3 = nodeLevel2->children;\r
-                       nodeLevel3 != NULL;\r
-                       nodeLevel3 = nodeLevel3->next)\r
-                       {\r
-\r
-                               DataFileStatus = 0;\r
-                               bool HREFFound = FALSE;\r
-                               bool ETagFound = FALSE;\r
-                               bool HTTPStatus = FALSE;\r
-\r
-                               if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||\r
-                               !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||\r
-                               !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")\r
-                               ){\r
-\r
-                                       // Get the filename.\r
-                                       \r
-                                       for (nodeLevel4 = nodeLevel3->children;\r
-                                       nodeLevel4 != NULL;\r
-                                       nodeLevel4 = nodeLevel4->next)\r
-                                       {\r
-                                       \r
-                                               if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||\r
-                                               !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||\r
-                                               !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")\r
-                                               ){\r
-                                               \r
-                                                       DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);\r
-                                                       wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));\r
-                                               \r
-                                                       while (wSTDFilename.HasMoreTokens()){\r
-                                                       \r
-                                                               DataFilename = wSTDFilename.GetNextToken();\r
-                                                       \r
-                                                       }\r
-                                                       \r
-                                                       HREFFound = TRUE;\r
-                                               \r
-                                               }\r
-                                               \r
-       \r
-                                       \r
-                                       }\r
-                                       \r
-\r
-                               } else {\r
-\r
-                                       for (nodeLevel4 = nodeLevel3->children;\r
-                                       nodeLevel4 != NULL;\r
-                                       nodeLevel4 = nodeLevel4->next)\r
-                                       {\r
-\r
-                                               for (nodeStatusLv1 = nodeLevel3->children;\r
-                                                       nodeStatusLv1 != NULL;\r
-                                                       nodeStatusLv1 = nodeStatusLv1->next)\r
-                                               {\r
-\r
-                                                       if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){\r
-               \r
-                                                               DataFileStatus = 2;\r
-                                                                               \r
-                                                               HTTPStatus = TRUE;\r
-                                                                               \r
-                                                       }\r
-                                       \r
-                                                       if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") ||\r
-                                                       !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") ||\r
-                                                       !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE)\r
-                                                       {\r
-\r
-                                                               // Get the filename.\r
-                                       \r
-                                                               for (nodeStatusLv2 = nodeStatusLv1->children;\r
-                                                               nodeStatusLv2 != NULL;\r
-                                                               nodeStatusLv2 = nodeStatusLv2->next)\r
-                                                               {\r
-                                       \r
-                                                                       if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") ||\r
-                                                                       !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") ||\r
-                                                                       !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text")\r
-                                                                       ){\r
-\r
-                                                                               if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){\r
-                                                                       \r
-                                                                                       DataFileStatus = 1;\r
-                                                                                       \r
-                                                                                       HTTPStatus = TRUE;\r
-                                                                       \r
-                                                                               // This is currently in a WebDAV draft and may hopefully be enabled when this changes.\r
-                                                                       \r
-                                                                               //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){\r
-                                                                               \r
-                                                                               //      DataFileStatus = 0;\r
-                                                                               \r
-                                                                               }\r
-                                               \r
-                                                                       }\r
-                                               \r
-       \r
-                                       \r
-                                                               }\r
-                                                       \r
-                                                       }\r
-\r
-                                       \r
-                                               }\r
-                                               \r
-                                               for (nodeLevel5 = nodeLevel4->children;\r
-                                               nodeLevel5 != NULL;\r
-                                               nodeLevel5 = nodeLevel5->next)\r
-                                               {\r
-\r
-                                                       if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||\r
-                                                       !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||\r
-                                                       !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")\r
-                                                       ){\r
-\r
-                                                               for (nodeLevel6 = nodeLevel5->children;\r
-                                                               nodeLevel6 != NULL;\r
-                                                               nodeLevel6 = nodeLevel6->next)\r
-                                                               {\r
-\r
-                                                                       // Strip the quotes from the ETag.\r
-                                               \r
-                                                                       ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);\r
-                                                                       if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){\r
-                                               \r
-                                                                               ETagData.Remove(0, 1);\r
-                                                                               ETagData.RemoveLast();\r
-                                               \r
-                                                                       }\r
-                                                               \r
-                                                                       ETagFound = TRUE;\r
-\r
-                                                               }\r
-                                                               \r
-                                                       }\r
-\r
-                                               }       \r
-\r
-                                       }\r
-\r
-                               }\r
-\r
-                               if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){\r
-                               \r
-                                       // Add to the map data.\r
-                                       \r
-                                       FileSyncData SData;\r
-                                       \r
-                                       SData.ETagData = ETagData;\r
-                                       SData.DataFlag = DataFileStatus;\r
-                                       \r
-                                       ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));\r
-                               \r
-                               }\r
-                               \r
-                               // Reset the values.\r
-                               \r
-                               HREFFound = FALSE;\r
-                               ETagFound = FALSE;\r
-                               HTTPStatus = FALSE;\r
-\r
-                       }\r
-\r
-                       if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") ||\r
-                       !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") ||\r
-                       !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) &&\r
-                       SyncTokenFound == FALSE\r
-                       ){\r
-\r
-                               for (nodeLevel3 = nodeLevel2->children;\r
-                               nodeLevel3 != NULL;\r
-                               nodeLevel3 = nodeLevel3->next)\r
-                               {\r
-\r
-                                       if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") ||\r
-                                       !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") ||\r
-                                       !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text")\r
-                                       ){\r
-                       \r
-                                               DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content);\r
-\r
-                                               SyncTokenFound = TRUE;\r
-                       \r
-                                       }\r
-                       \r
-                               }\r
-       \r
-                       }\r
-\r
-               }\r
-\r
-       }\r
-       \r
-       for (nodeLevel1 = xmlCardDAVDoc->children;\r
-               nodeLevel1 != NULL;\r
-               nodeLevel1 = nodeLevel1->next)\r
-       {\r
-\r
-               for (nodeLevel2 = nodeLevel1->children;\r
-                       nodeLevel2 != NULL;\r
-                       nodeLevel2 = nodeLevel2->next)\r
-               {\r
-\r
-                       DataFileStatus = 0;\r
-                       bool HREFFound = FALSE;\r
-                       bool ETagFound = FALSE;\r
-                       bool HTTPStatus = FALSE;\r
-\r
-                       for (nodeLevel3 = nodeLevel2->children;\r
-                       nodeLevel3 != NULL;\r
-                       nodeLevel3 = nodeLevel3->next)\r
-                       {\r
-\r
-                               if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||\r
-                               !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||\r
-                               !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")\r
-                               ){\r
-\r
-                                       // Get the filename.\r
-                                       \r
-                                       for (nodeLevel4 = nodeLevel3->children;\r
-                                       nodeLevel4 != NULL;\r
-                                       nodeLevel4 = nodeLevel4->next)\r
-                                       {\r
-                                       \r
-                                               if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||\r
-                                               !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||\r
-                                               !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")\r
-                                               ){\r
-                                               \r
-                                                       DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);\r
-                                                       wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));\r
-                                               \r
-                                                       while (wSTDFilename.HasMoreTokens()){\r
-                                                       \r
-                                                               DataFilename = wSTDFilename.GetNextToken();\r
-                                                       \r
-                                                       }\r
-                                                       \r
-                                                       HREFFound = TRUE;\r
-                                               \r
-                                               }\r
-                                               \r
-       \r
-                                       \r
-                                       }\r
-                                       \r
-\r
-                               } else {\r
-\r
-                                       for (nodeLevel4 = nodeLevel3->children;\r
-                                       nodeLevel4 != NULL;\r
-                                       nodeLevel4 = nodeLevel4->next)\r
-                                       {\r
-\r
-                                               for (nodeStatusLv1 = nodeLevel3->children;\r
-                                                       nodeStatusLv1 != NULL;\r
-                                                       nodeStatusLv1 = nodeStatusLv1->next)\r
-                                               {\r
-\r
-                                                       if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){\r
-               \r
-                                                               DataFileStatus = 2;\r
-\r
-                                                               HTTPStatus = TRUE;\r
-                                                                               \r
-                                                       }\r
-                                       \r
-                                                       if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") ||\r
-                                                       !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") ||\r
-                                                       !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE)\r
-                                                       {\r
-\r
-                                                               // Get the filename.\r
-                                       \r
-                                                               for (nodeStatusLv2 = nodeStatusLv1->children;\r
-                                                               nodeStatusLv2 != NULL;\r
-                                                               nodeStatusLv2 = nodeStatusLv2->next)\r
-                                                               {\r
-                                       \r
-                                                                       if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") ||\r
-                                                                       !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") ||\r
-                                                                       !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text")\r
-                                                                       ){\r
-\r
-                                                                               if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){\r
-\r
-                                                                                       DataFileStatus = 1;\r
-                                                                                       \r
-                                                                                       HTTPStatus = TRUE;\r
-                                                                       \r
-                                                                               // This is currently in a WebDAV draft and may hopefully be enabled when this changes.\r
-                                                                       \r
-                                                                               //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){\r
-                                                                               \r
-                                                                               //      DataFileStatus = 0;\r
-                                                                               \r
-                                                                               }\r
-                                               \r
-                                                                       }\r
-                                               \r
-       \r
-                                       \r
-                                                               }\r
-                                                       \r
-                                                       }\r
-\r
-                                       \r
-                                               }\r
-                                               \r
-                                               for (nodeLevel5 = nodeLevel4->children;\r
-                                               nodeLevel5 != NULL;\r
-                                               nodeLevel5 = nodeLevel5->next)\r
-                                               {\r
-\r
-                                                       if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||\r
-                                                       !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||\r
-                                                       !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")\r
-                                                       ){\r
-\r
-                                                               for (nodeLevel6 = nodeLevel5->children;\r
-                                                               nodeLevel6 != NULL;\r
-                                                               nodeLevel6 = nodeLevel6->next)\r
-                                                               {\r
-\r
-                                                                       // Strip the quotes from the ETag.\r
-                                               \r
-                                                                       ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);\r
-                                                                       if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){\r
-                                               \r
-                                                                               ETagData.Remove(0, 1);\r
-                                                                               ETagData.RemoveLast();\r
-                                               \r
-                                                                       }\r
-                                                               \r
-                                                                       ETagFound = TRUE;\r
-\r
-                                                               }\r
-                                                               \r
-                                                       }\r
-\r
-                                               }       \r
-\r
-                                       }\r
-\r
-                               }\r
-\r
-                       }\r
-\r
-                       if (HREFFound == TRUE && HTTPStatus == TRUE && DataFileStatus == 2){\r
-                       \r
-                               FileSyncData SData;\r
-                                       \r
-                               SData.ETagData = wxT("");\r
-                               SData.DataFlag = DataFileStatus;\r
-                                       \r
-                               ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));                          \r
-                       \r
-                       }\r
-\r
-                       if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){\r
-                               \r
-                               // Add to the map data.\r
-                                       \r
-                               FileSyncData SData;\r
-                                       \r
-                               SData.ETagData = ETagData;\r
-                               SData.DataFlag = DataFileStatus;\r
-                                       \r
-                               ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));\r
-                               \r
-                       }\r
-                               \r
-                       // Reset the values.\r
-                               \r
-                       HREFFound = FALSE;\r
-                       ETagFound = FALSE;\r
-                       HTTPStatus = FALSE;\r
-                       DataFilename.Clear();\r
-\r
-                       if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") ||\r
-                       !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") ||\r
-                       !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) &&\r
-                       SyncTokenFound == FALSE\r
-                       ){\r
-\r
-                               for (nodeLevel3 = nodeLevel2->children;\r
-                               nodeLevel3 != NULL;\r
-                               nodeLevel3 = nodeLevel3->next)\r
-                               {\r
-\r
-                                       if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") ||\r
-                                       !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") ||\r
-                                       !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text")\r
-                                       ){\r
-                       \r
-                                               DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content);\r
-\r
-                                               SyncTokenFound = TRUE;\r
-                       \r
-                                       }\r
-                       \r
-                               }\r
-       \r
-                       }\r
-\r
-               }\r
-\r
-       }\r
-       \r
-       // Get the sync token.\r
-       \r
-       if (SyncTokenFound == TRUE){\r
-       \r
-               ContactListFinal.SyncToken = DataSyncToken;\r
-       \r
-       } else {\r
-       \r
-       }\r
-\r
-       SleepFor(2000000000);\r
-\r
-       /*timespec n1, n2;\r
-                                               \r
-       n1.tv_sec = 0;\r
-       n1.tv_nsec = 2000000000L;\r
-               \r
-       nanosleep(&n1, &n2);*/\r
-\r
-       xmlFreeDoc(xmlCardDAVDoc);\r
-       curl_easy_cleanup(conn);\r
-\r
-       SyncDataBuffer.reset();\r
-\r
-       // Get the first result.\r
-\r
-       return ContactListFinal;\r
-\r
-}\r
-\r
-int CardDAV::GetResultCode(){\r
-\r
-       return (int)claconncode;\r
-\r
-}\r
-\r
-int CardDAV::GetHTTPCode(){\r
-\r
-       return HTTPErrorCode;\r
-\r
-}\r
-\r
-wxString CardDAV::GetErrorBuffer(){\r
-\r
-       wxString ErrorBuffer = wxString::FromUTF8(curlerrbuffer);\r
+       wxString ErrorBuffer = wxString::FromUTF8(curlerrbuffer);\r
 \r
        return ErrorBuffer;\r
 \r
 }\r
 \r
-wxString CardDAV::GetDefaultAddressBookURL(){\r
-\r
-       // First: Get the principal UID address.\r
-       \r
-       PageData.Clear();\r
-       PageHeader.Clear();\r
-\r
-       SSLStatus = TRUE;\r
-       AuthPassed = TRUE;\r
-       AbortConnection = FALSE;\r
-\r
-       CURL *conn;\r
-       CURLcode conncode;\r
-       wxString ServerAddressURL;\r
-       wxString ServerAuth;\r
-       wxString ServerAddressSSL;\r
-       wxString ServerAddressNormal;   \r
-\r
-       conn = curl_easy_init();\r
-       \r
-       struct curl_slist *connhd = NULL;\r
-       struct curl_slist *connhd2 = NULL;\r
-       struct curl_slist *connhd3 = NULL;\r
-\r
-       connhd = curl_slist_append(connhd, "Depth: 0");\r
-       connhd = curl_slist_append(connhd, "Prefer: return-minimal");\r
-       connhd = curl_slist_append(connhd, "Content-Type: application/xml; charset=utf-8");\r
-\r
-       connhd2 = curl_slist_append(connhd2, "Depth: 0");\r
-       connhd2 = curl_slist_append(connhd2, "Prefer: return-minimal");\r
-       connhd2 = curl_slist_append(connhd2, "Content-Type: application/xml; charset=utf-8");\r
-\r
-       connhd3 = curl_slist_append(connhd3, "Depth: 1");\r
-       connhd3 = curl_slist_append(connhd3, "Prefer: return-minimal");\r
-       connhd3 = curl_slist_append(connhd3, "Content-Type: application/xml; charset=utf-8");\r
-\r
-       struct CardDAVCURLPasser {\r
-       \r
-               CardDAV *Data;\r
-               bool HeaderMode = TRUE;\r
-       \r
-       } CardDAVHeader, CardDAVFooter;\r
-\r
-       CardDAVHeader.Data = this;\r
-       CardDAVHeader.HeaderMode = TRUE;\r
-       \r
-       CardDAVFooter.Data = this;\r
-       CardDAVFooter.HeaderMode = FALSE;\r
-\r
-       wxString Data1;\r
-       wxString Data2;\r
-       \r
-       wxString ETag;\r
-       wxString ETagOriginal;\r
-       wxString ETagServer;\r
-       \r
-       ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");\r
-       ServerAddressSSL = wxT("https://") + ServerAddressURL;\r
-       ServerAddressNormal = wxT("http://") + ServerAddressURL;\r
-       \r
-       ServerAuth = ServerUser + wxT(":") + ServerPass;\r
-       \r
-       wxString SAURLPrincipals;\r
-       wxString SAURLPrincipalURL;\r
-       wxString SAURLAddressURL;\r
-       \r
-       if (ServerSSL){\r
-       \r
-               SAURLPrincipals = ServerAddressSSL + wxT("principals/");\r
-               SAURLPrincipalURL = ServerAddressSSL;\r
-               SAURLAddressURL = ServerAddressSSL;\r
-       \r
-       } else {\r
-       \r
-               SAURLPrincipals = ServerAddressNormal + wxT("principals/");\r
-               SAURLPrincipalURL = ServerAddressNormal;\r
-               SAURLAddressURL = ServerAddressNormal;\r
-       \r
-       }\r
-       \r
-       wxString FinalPrefix;\r
-\r
-       struct UploadDataStruc UploadData;\r
-       \r
-       // Setup the first query finding out where the principal URL is.\r
-       \r
-       const char* query = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"\r
-               "<D:propfind xmlns:D=\"DAV:\">\n"\r
-               " <D:prop>"\r
-               "  <D:current-user-principal/>\n"\r
-               " </D:prop>"\r
-               "</D:propfind>";\r
-\r
-       // Setup the second query finding out where the address book home URL is.\r
-       \r
-       const char* query2 = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"\r
-       "<D:propfind xmlns:D=\"DAV:\""\r
-       "  xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"\r
-       "  <D:prop>\n"\r
-       "    <C:addressbook-home-set/>\n"\r
-       "  </D:prop>\n"\r
-       "</D:propfind>";\r
-       \r
-       // Setup the third query finding out where the default address book URL is.\r
-       \r
-       const char* query3 = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"\r
-       "<D:propfind xmlns:D=\"DAV:\""\r
-       "  xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"\r
-       "  <D:prop>\n"\r
-       "    <C:default-addressbook-URL/>\n"    \r
-       "  </D:prop>\n"\r
-       "</D:propfind>";\r
-       \r
-       if (ServerSSL){\r
-\r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipals.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));\r
-               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd);\r
-               \r
-               if (AllowSelfSign == TRUE){\r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L);\r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L);\r
-               }\r
-\r
-               conncode = (curl_easy_perform(conn));\r
-\r
-               if (conncode == CURLE_OK){\r
-\r
-                       *ServerResult = TRUE;\r
-                       AuthPassed = TRUE;\r
-                       ValidResponse = TRUE;\r
-                       SSLStatus = TRUE;\r
-\r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));                                  \r
-                                       \r
-                       *ServerResult = FALSE;\r
-                       \r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);\r
-                       \r
-                       return wxT("");                                 \r
-\r
-               }\r
-\r
-       } else {\r
-       \r
-               // No SSL.\r
-\r
-               // Do an initial connection (incase of Digest authentication).\r
-\r
-               PageData.Clear();\r
-               PageHeader.Clear();\r
-\r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipals.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));\r
-               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd);\r
-               \r
-               conncode = (curl_easy_perform(conn));\r
-\r
-               // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG,\r
-               // then bring up the conflict resolution form.\r
-               \r
-               if (EditMode == TRUE){\r
-               \r
-               }\r
-\r
-               if (conncode == CURLE_OK){\r
-\r
-               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
-\r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);\r
-               \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-\r
-                       fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",\r
-                                       GetHTTPCode());\r
-\r
-                       return wxT("");\r
-               \r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-                       return wxT("");\r
-\r
-               }\r
-\r
-       }\r
-       \r
-       // Process the XML data from the application.\r
-       \r
-       xmlDocPtr xmlCardDAVDoc;\r
-       xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);\r
-\r
-       xmlNodePtr nodeLevel1;\r
-       xmlNodePtr nodeLevel2;\r
-       xmlNodePtr nodeLevel3;\r
-       xmlNodePtr nodeLevel4;\r
-       xmlNodePtr nodeLevel5;\r
-       xmlNodePtr nodeLevel6;\r
-       xmlNodePtr nodeLevel7;\r
-               \r
-       for (nodeLevel1 = xmlCardDAVDoc->children;\r
-               nodeLevel1 != NULL;\r
-               nodeLevel1 = nodeLevel1->next)\r
-       {\r
-\r
-               for (nodeLevel2 = nodeLevel1->children;\r
-                       nodeLevel2 != NULL;\r
-                       nodeLevel2 = nodeLevel2->next)\r
-               {\r
-\r
-\r
-                       for (nodeLevel3 = nodeLevel2->children;\r
-                       nodeLevel3 != NULL;\r
-                       nodeLevel3 = nodeLevel3->next)\r
-                       {\r
-                       \r
-                               for (nodeLevel4 = nodeLevel3->children;\r
-                               nodeLevel4 != NULL;\r
-                               nodeLevel4 = nodeLevel4->next)\r
-                               {\r
-                       \r
-                                       for (nodeLevel5 = nodeLevel4->children;\r
-                                       nodeLevel5 != NULL;\r
-                                       nodeLevel5 = nodeLevel5->next)\r
-                                       {\r
-                       \r
-                                               for (nodeLevel6 = nodeLevel5->children;\r
-                                               nodeLevel6 != NULL;\r
-                                               nodeLevel6 = nodeLevel6->next)\r
-                                               {\r
-                       \r
-                                                       if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||\r
-                                                       !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||\r
-                                                       !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")\r
-                                                       ){\r
-                       \r
-                                                               // Found the <href> part so extract the principal URL address.\r
-                                                               \r
-                                                               for (nodeLevel7 = nodeLevel6->children;\r
-                                                               nodeLevel7 != NULL;\r
-                                                               nodeLevel7 = nodeLevel7->next)\r
-                                                               {\r
-                                                               \r
-                                                                       SAURLPrincipalURL.Append(wxString::FromUTF8((const char*)nodeLevel7->content));\r
-                       \r
-                                                               }\r
-                       \r
-                                                       }\r
-                       \r
-                                               }\r
-                       \r
-                                       }\r
-                       \r
-                               }\r
-                       \r
-                       }\r
-               \r
-               }\r
-               \r
-       }\r
-       \r
-       xmlFreeDoc(xmlCardDAVDoc);\r
-       PageData.Clear();\r
-       PageHeader.Clear();\r
-               \r
-       // Second: Get the addressbook-home-set \r
-\r
-       curl_easy_reset(conn);\r
-\r
-       if (ServerSSL){\r
-\r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipalURL.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query2);\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query2));\r
-               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd2);\r
-\r
-               if (AllowSelfSign == TRUE){\r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L);\r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L);\r
-               }\r
-\r
-               conncode = (curl_easy_perform(conn));\r
-\r
-               if (conncode == CURLE_OK){\r
-\r
-                       *ServerResult = TRUE;\r
-                       AuthPassed = TRUE;\r
-                       SSLStatus = TRUE;\r
-\r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));                                  \r
-                                       \r
-                       *ServerResult = FALSE;\r
-                       ValidResponse = FALSE;\r
-                       \r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);\r
-                       \r
-                       return wxT("");                                 \r
-\r
-               }\r
-\r
-       } else {\r
-       \r
-       // No SSL.\r
-               \r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLPrincipalURL.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query2);\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query2));\r
-               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd2);\r
-               \r
-               conncode = (curl_easy_perform(conn));\r
-               \r
-               // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG,\r
-               // then bring up the conflict resolution form.\r
-               \r
-               if (EditMode == TRUE){\r
-               \r
-               }\r
-\r
-               if (conncode == CURLE_OK){\r
-\r
-               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
-\r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);\r
-               \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-\r
-                       fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",\r
-                                       GetHTTPCode());\r
-                       \r
-                       ValidResponse = FALSE;\r
-                       \r
-                       return wxT("");\r
-               \r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-                       \r
-                       ValidResponse = FALSE;\r
-                       \r
-                       return wxT("");\r
-\r
-               }\r
-               \r
-       }\r
-\r
-       xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);\r
-               \r
-       for (nodeLevel1 = xmlCardDAVDoc->children;\r
-               nodeLevel1 != NULL;\r
-               nodeLevel1 = nodeLevel1->next)\r
-       {\r
-\r
-               for (nodeLevel2 = nodeLevel1->children;\r
-                       nodeLevel2 != NULL;\r
-                       nodeLevel2 = nodeLevel2->next)\r
-               {\r
-\r
-\r
-                       for (nodeLevel3 = nodeLevel2->children;\r
-                       nodeLevel3 != NULL;\r
-                       nodeLevel3 = nodeLevel3->next)\r
-                       {\r
-                       \r
-                               for (nodeLevel4 = nodeLevel3->children;\r
-                               nodeLevel4 != NULL;\r
-                               nodeLevel4 = nodeLevel4->next)\r
-                               {\r
-                       \r
-                                       for (nodeLevel5 = nodeLevel4->children;\r
-                                       nodeLevel5 != NULL;\r
-                                       nodeLevel5 = nodeLevel5->next)\r
-                                       {\r
-                       \r
-                                               for (nodeLevel6 = nodeLevel5->children;\r
-                                               nodeLevel6 != NULL;\r
-                                               nodeLevel6 = nodeLevel6->next)\r
-                                               {\r
-                       \r
-                                                       if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||\r
-                                                       !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||\r
-                                                       !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")\r
-                                                       ){\r
-                       \r
-                                                               // Found the <href> part so extract the principal URL address.\r
-                                                               \r
-                                                               for (nodeLevel7 = nodeLevel6->children;\r
-                                                               nodeLevel7 != NULL;\r
-                                                               nodeLevel7 = nodeLevel7->next)\r
-                                                               {\r
-                                                               \r
-                                                                       SAURLAddressURL.Append(wxString::FromUTF8((const char*)nodeLevel7->content));\r
-                       \r
-                                                               }\r
-                       \r
-                                                       }\r
-                       \r
-                                               }\r
-                       \r
-                                       }\r
-                       \r
-                               }\r
-                       \r
-                       }\r
-               \r
-               }\r
-               \r
-       }\r
-\r
-       xmlFreeDoc(xmlCardDAVDoc);\r
-       PageData.Clear();\r
-       PageHeader.Clear();\r
-\r
-       // Finally: Get the default-addressbook-URL from the addressbook-home-set address.\r
-               \r
-       curl_easy_reset(conn);\r
-\r
-       if (ServerSSL){\r
-\r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLAddressURL.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             \r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query3);\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query3));\r
-               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd3);\r
-\r
-               if (AllowSelfSign == TRUE){\r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L);\r
-                       curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L);\r
-               }\r
-\r
-               conncode = (curl_easy_perform(conn));\r
-\r
-               if (conncode == CURLE_OK){\r
-\r
-                       *ServerResult = TRUE;\r
-                       AuthPassed = TRUE;\r
-                       SSLStatus = TRUE;\r
-\r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));                                  \r
-                                       \r
-                       *ServerResult = FALSE;\r
-                       ValidResponse = FALSE;\r
-                       \r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);\r
-                       \r
-                       return wxT("");                                 \r
-\r
-               }\r
-\r
-       } else {\r
-       \r
-       // No SSL.\r
-               \r
-               curl_easy_setopt(conn, CURLOPT_URL, (const char*)SAURLAddressURL.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);\r
-               curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);\r
-               curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);\r
-               curl_easy_setopt(conn, CURLOPT_FAILONERROR, FALSE);\r
-               curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);\r
-               curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));\r
-               curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);\r
-               curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);\r
-               curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);\r
-               curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);\r
-               curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "PROPFIND");\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query3);\r
-               curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query3));\r
-               curl_easy_setopt(conn, CURLOPT_HTTPHEADER, connhd3);\r
-               \r
-               conncode = (curl_easy_perform(conn));\r
-               \r
-               // If the ETag is different to the non-matching X-XAB-ETAG and X-XAB-ETAG-ORIG,\r
-               // then bring up the conflict resolution form.\r
-               \r
-               if (EditMode == TRUE){\r
-               \r
-               }\r
-\r
-               if (conncode == CURLE_OK){\r
-\r
-               } else if (conncode == CURLE_HTTP_RETURNED_ERROR){\r
-\r
-                       curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &HTTPErrorCode);\r
-               \r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-\r
-                       fprintf(stderr, "curl_easy_perform() HTTP code was: %i\n",\r
-                                       GetHTTPCode());\r
-                                       \r
-                       ValidResponse = FALSE;\r
-                                       \r
-                       return wxT("");\r
-               \r
-               } else {\r
-\r
-                       fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
-                                       curl_easy_strerror(conncode));\r
-                                       \r
-                       ValidResponse = FALSE;\r
-                                       \r
-                       return wxT("");\r
-\r
-               }\r
-               \r
-       }\r
-       \r
-       xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);\r
-               \r
-       for (nodeLevel1 = xmlCardDAVDoc->children;\r
-               nodeLevel1 != NULL;\r
-               nodeLevel1 = nodeLevel1->next)\r
-       {\r
-\r
-               for (nodeLevel2 = nodeLevel1->children;\r
-                       nodeLevel2 != NULL;\r
-                       nodeLevel2 = nodeLevel2->next)\r
-               {\r
-\r
-\r
-                       for (nodeLevel3 = nodeLevel2->children;\r
-                       nodeLevel3 != NULL;\r
-                       nodeLevel3 = nodeLevel3->next)\r
-                       {\r
-                       \r
-                               for (nodeLevel4 = nodeLevel3->children;\r
-                               nodeLevel4 != NULL;\r
-                               nodeLevel4 = nodeLevel4->next)\r
-                               {\r
-                       \r
-                                       for (nodeLevel5 = nodeLevel4->children;\r
-                                       nodeLevel5 != NULL;\r
-                                       nodeLevel5 = nodeLevel5->next)\r
-                                       {\r
-                       \r
-                                               for (nodeLevel6 = nodeLevel5->children;\r
-                                               nodeLevel6 != NULL;\r
-                                               nodeLevel6 = nodeLevel6->next)\r
-                                               {\r
-                       \r
-                                                       if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||\r
-                                                       !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||\r
-                                                       !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")\r
-                                                       ){\r
-                       \r
-                                                               // Found the <href> part so extract the principal URL address.\r
-                                                               \r
-                                                               for (nodeLevel7 = nodeLevel6->children;\r
-                                                               nodeLevel7 != NULL;\r
-                                                               nodeLevel7 = nodeLevel7->next)\r
-                                                               {\r
-                                                               \r
-                                                                       FinalPrefix = wxString::FromUTF8((const char*)nodeLevel7->content);\r
-                       \r
-                                                               }\r
-                       \r
-                                                       }\r
-                       \r
-                                               }\r
-                       \r
-                                       }\r
-                       \r
-                               }\r
-                       \r
-                       }\r
-               \r
-               }\r
-               \r
-       }\r
-\r
-       xmlFreeDoc(xmlCardDAVDoc);\r
-       PageData.Clear();\r
-       PageHeader.Clear();\r
-\r
-       return FinalPrefix;\r
-\r
-}\r
-\r
 SSLCertCollection CardDAV::BuildSSLCollection(CURL *conn){\r
 \r
        SSLCertCollection SSLCertInfo;\r
index e38c614..dbbcc9b 100644 (file)
@@ -21,6 +21,12 @@ struct ContactListData{
        std::map<wxString,FileSyncData> ListData;
 };
 
+struct UploadDataStruc{
+       wxString *readptr;
+       long sizeleft;
+       int seek = 0;
+};
+
 /*struct CertificateData{
        std::multimap<wxString,wxString> CertificateData;
        bool CertValid;
@@ -38,6 +44,7 @@ struct CertificateCollection{
 
 size_t WritebackFunc(char *ptr, size_t size, size_t nmemb, wxString *userdata);
 int ProgressFunc(void *clientdata, double TTDown, double NDown, double TTUp, double NUp);
+size_t UploadReadFunc(void *ptr, size_t size, size_t nmemb, void *userdata);
 
 class CardDAV
 {
Xestia Software Development
Yn Maystri
© 2006 - 2019 Xestia Software Development
Software

Xestia Address Book
Xestia Calendar
Development

Xestia Gelforn
Everything else

About
News
Privacy Policy