-// carddav-contactlist.cpp - CardDAV Object - Contact list subroutines.
-//
-// (c) 2012-2015 Xestia Software Development.
-//
-// This file is part of Xestia Address Book.
-//
-// Xestia Address Book is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by the
-// Free Software Foundation, version 3 of the license.
-//
-// Xestia Address Book is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with Xestia Address Book. If not, see <http://www.gnu.org/licenses/>
-
-#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){
-
- // Get the contact list.
-
- 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();
-
-#if defined(__APPLE__)
-
- SetConnectionObject(conn);
-
-#endif
-
- 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) + ServerPrefix;
- 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.Append(SyncTokenInc);
- 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();
-
- }
-
- 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);
-
-#if defined(__APPLE__) || defined(__WIN32__)
-
-#else
-
- 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));
-
- }
-
-#endif
-
- 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 defined(__APPLE__)
-
-#else
-
- if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
-
- CURL *sslerrconn;
- sslerrconn = curl_easy_init();
- CURLcode sslerrconncode;
-
- 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);
-
- }
-
-#endif
-
- // 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);
-
-#if defined(__APPLE__)
-
- SetConnectionObject(sslerrconn);
-
-#endif
-
- 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);
- 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);
-
- xmlFreeDoc(xmlCardDAVDoc);
- curl_easy_cleanup(conn);
-
- SyncDataBuffer.reset();
-
- // Get the first result.
-
- return ContactListFinal;
-
-}
\ No newline at end of file