Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Altered CardDAV object to accommodate for SSL support for OS X (and other OSes in...
[xestiaab/.git] / source / carddav / carddav-contactlist.cpp
1 // carddav-contactlist.cpp - CardDAV Object - Contact list subroutines.
2 //
3 // (c) 2012-2015 Xestia Software Development.
4 //
5 // This file is part of Xestia Address Book.
6 //
7 // Xestia Address Book is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
10 //
11 // Xestia Address Book is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Address Book. If not, see <http://www.gnu.org/licenses/>
19 #include "carddav.h"
20 #include "../version.h"
21 #include <wx/wx.h>
22 #include <wx/tokenzr.h>
23 #include <wx/ffile.h>
24 #include <libxml/parser.h>
25 #include <libxml/tree.h>
26 #include <map>
27 #include <thread>
28 #include "../vcard/vcard.h"
29 #include "../common/dirs.h"
31 ContactListData CardDAV::GetContactList(wxString SyncTokenInc){
33         // Get the contact list.
34         
35         ContactListData ContactListFinal;
36         std::map<wxString,FileSyncData> ContactList;
37         
38         PageData.Clear();
39         PageHeader.Clear();
41         SSLStatus = TRUE;
42         AuthPassed = TRUE;
43         AbortConnection = FALSE;
45         CURL *conn;
46         wxString ServerAddressURL;
47         wxString ServerAuth;
48         wxString ServerAddressSSL;
49         wxString ServerAddressNormal;
51         conn = curl_easy_init();
53 #if defined(__APPLE__)
54         SetConnectionObject(conn);
55 #endif
56         
57         struct CardDAVCURLPasser {
58         
59                 CardDAV *Data;
60                 bool HeaderMode = TRUE;
61         
62         } CardDAVHeader, CardDAVFooter;
64         CardDAVHeader.Data = this;
65         CardDAVHeader.HeaderMode = TRUE;
66         
67         CardDAVFooter.Data = this;
68         CardDAVFooter.HeaderMode = FALSE;
70         wxString Data1;
71         wxString Data2;
72         
73         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + ServerPrefix;
74         ServerAddressSSL = wxT("https://") + ServerAddressURL;
75         ServerAddressNormal = wxT("http://") + ServerAddressURL;
76         
77         ServerAuth = ServerUser + wxT(":") + ServerPass;
78         
79         // Load the sync token file (if it exists).
80         
81         wxCharBuffer SyncDataBuffer;
82         wxString SyncData;
83         
84         SyncData.Clear();
85         
86         SyncTokenInc.Trim();
87         
88         if (!SyncTokenInc.IsEmpty()){
89                 
90                 SyncData = wxT("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
91                 SyncData.Append(wxT("<D:sync-collection xmlns:D=\"DAV:\"\n"));
92                 SyncData.Append(wxT(" xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"));
93                 SyncData.Append(wxT("<D:sync-token>"));
94                 SyncData.Append(SyncTokenInc);
95                 SyncData.Append(wxT("</D:sync-token>\n"));
96                 SyncData.Append(wxT("<D:sync-level>1</D:sync-level>\n"));
97                 SyncData.Append(wxT("<D:prop>\n"));
98                 SyncData.Append(wxT("   <D:getetag/>\n"));
99                 SyncData.Append(wxT("</D:prop>\n"));
100                 SyncData.Append(wxT("</D:sync-collection>"));
101                 
102                 SyncDataBuffer = SyncData.ToUTF8();
103         
104         } else {
105                 
106                 SyncData = wxT("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
107                 SyncData.Append(wxT("<D:sync-collection xmlns:D=\"DAV:\""));
108                 SyncData.Append(wxT(" xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"));
109                 SyncData.Append(wxT("<D:sync-token/>\n"));
110                 SyncData.Append(wxT("<D:sync-level>1</D:sync-level>\n"));
111                 SyncData.Append(wxT("<D:prop>\n"));
112                 SyncData.Append(wxT("   <D:getetag/>\n"));
113                 SyncData.Append(wxT("</D:prop>\n"));
114                 SyncData.Append(wxT("</D:sync-collection>\n"));
115                 
116                 SyncDataBuffer = SyncData.ToUTF8();
118         }
120         const char* query = SyncDataBuffer.data();
121         
122         // Try SSL first.
124         std::map<int,int>::iterator ActIter;
125         struct UploadDataStruc UploadData;
126         
127         ActIter = ActivityListPtr->find((int)ItemIndex);
129         curl_slist *slist = NULL;       
131         slist = curl_slist_append(slist, "Depth: 1");
133         if (ServerSSL){
135                 wxString ServerCertFilename;
136                 bool MatchingCert = FALSE;
138                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
139                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
140                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
141                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
142                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
143                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
144                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
145                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
146                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
147                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
148                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
149                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
150                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
151                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
152                 curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
153                 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
155 #if defined(__APPLE__)
156                 
157 #else
158                 
159                 ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
161                 if (wxFile::Exists(ServerCertFilename) == TRUE){
162                 
163                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
164                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
165                         curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
166                 
167                 }
169 #endif
170                 
171                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
172                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
174                 claconncode = (curl_easy_perform(conn));
176                 // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without
177                 // the local certificate in use.
179                 if (claconncode == CURLE_PEER_FAILED_VERIFICATION){
180                         
181                         curl_easy_cleanup(conn);
182                         conn = curl_easy_init();
183                         
184                         curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
185                         curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
186                         curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
187                         curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
188                         curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
189                         curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
190                         curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
191                         curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
192                         curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
193                         curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
194                         curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
195                         curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
196                         curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
197                         curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
198                         curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
199                         curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
200                         curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
201                         curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
202                         
203                         claconncode = (curl_easy_perform(conn));
204                         
205                         // If claconncode is CURLE_OK then delete the certificate file as that
206                         // is no longer needed.
207                         
208                         if (claconncode == CURLE_OK){
209                         
210                                 // Delete the certificate file.
211                                 
212                                 wxRemoveFile(ServerCertFilename);
213                         
214                         }
215                 
216                 }
218                 // Check if it fails with a CURLE_SSL_CACERT then compare
219                 // the certificates as PEM files.
220                 
221 #if defined(__APPLE__)
223 #else
224                 
225                 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
227                         CURL *sslerrconn;
228                         sslerrconn = curl_easy_init();
229                         CURLcode sslerrconncode;
230                         
231                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
233                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
234                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
235                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
236                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
237                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
238                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
239                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
240                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
241                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
242                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
243                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
244                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
245                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
246                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
247                 
248                         wxString SSLLocalData;
249                         wxString SSLServerData;
250                 
251                         sslerrconncode = (curl_easy_perform(sslerrconn));
252                 
253                         SSLCertCol = BuildSSLCollection(sslerrconn);
254                         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);
255                         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
256                         
257                         wxFFile SSLLocalFile;
258                         
259 #if wxABI_VERSION < 20900
260                         SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
261 #else
262                         SSLLocalFile.Open(ServerCertFilename, wxT("r"));
263 #endif  
264         
265                         // Load the recovery database for tasks not done.
266         
267                         if (SSLLocalFile.IsOpened() == TRUE){
269                         // Check if we are using wxWidgets version 2.8 or less and
270                         // execute the required command accordingly.
271         
272                                 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
273                 
274         
275                         }
276                         
277                         SSLServerData = SSLDataIter->second;
278                         
279                         if (SSLLocalData == SSLServerData){
280                         
281                                 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
282                                 // and CURLOPT_SSL_VERIFYHOST off.
283                         
284                                 curl_easy_cleanup(conn);
285                                 conn = curl_easy_init();
286                                 
287                                 PageHeader.clear();
288                                 PageData.clear();
289                                 
290                                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
291                                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
292                                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
293                                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
294                                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
295                                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
296                                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
297                                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
298                                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
299                                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
300                                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
301                                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
302                                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
303                                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
304                                 curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
305                                 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
306                                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
307                                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
308                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);
309                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);
310                         
311                                 claconncode = (curl_easy_perform(conn));
312                                 
313                                 MatchingCert = TRUE;
314                         
315                         }
316                         
317                         if (MatchingCert == FALSE){
318                 
319                                 claconncode = CURLE_SSL_CACERT;
320                                 return ContactListFinal;
321                 
322                         }
323                         
324                         curl_easy_cleanup(sslerrconn);
325                 
326                 }
327                 
328 #endif
330                 // Sort out SSL error.
331                 
332                 // When SSL cert error occurs, connect again and fetch certificates.
333                 // Display a message to the user explaining that an invalid
334                 // certificate has been given and let the user decide what
335                 // to do next.
337                 if (claconncode == CURLE_OK){
339                 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
340                 
341                         CURL *sslerrconn;
342                         sslerrconn = curl_easy_init();
343                         CURLcode sslerrconncode;
344                 
345                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
346                 
347                         // Replace conn with sslerrconn!
348                 
349                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
350                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
351                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
352                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
353                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
354                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
355                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
356                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
357                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
358                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
359                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
360                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
361                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
362                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
363                 
364 #if defined(__APPLE__)
365                         SetConnectionObject(sslerrconn);
366 #endif
367                         
368                         sslerrconncode = (curl_easy_perform(sslerrconn));
370                         SSLCertCol = BuildSSLCollection(sslerrconn);
371                         SSLCertCol.SuccessCode = 1;
373                         return ContactListFinal;
374                 
375                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
376                 
377                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
378                                         curl_easy_strerror(claconncode));
379                         int http_code = 0;
380                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
381                         fprintf(stderr, "Error code was: %d\n", http_code);
382                                         
383                         return ContactListFinal;
384                 
385                 } else {
387                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
388                                         curl_easy_strerror(claconncode));
389                         int http_code = 0;
390                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
391                         fprintf(stderr, "Error code was: %d\n", http_code);
393                         return ContactListFinal;
395                 }
397                 SSLCertCol = BuildSSLCollection(conn);
399         } else {
400         
401         // No SSL.
402                 
403                 wxString EmptyString;
404                 
405                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
406                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
407                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
408                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
409                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
410                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
411                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
412                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
413                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
414                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
415                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
416                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
417                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
418                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
419                 curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
420                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
421                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));           
422                 
423                 PageData.Clear();
424                 PageHeader.Clear();
425                 
426                 claconncode = (curl_easy_perform(conn));
428                 if (claconncode == CURLE_OK){
432                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
433                 
434                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
435                                         curl_easy_strerror(claconncode));
436                         int http_code = 0;
437                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
438                         fprintf(stderr, "Error code was: %i\n", http_code);
439                                         
440                         return ContactListFinal;
441                         
442                 } else {
444                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
445                                         curl_easy_strerror(claconncode));
446                         int http_code = 0;
447                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
448                         fprintf(stderr, "Error code was: %i\n", http_code);
449                                 
450                         return ContactListFinal;
452                 }
453                 
454         }
456         xmlDocPtr xmlCardDAVDoc;
457         xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);
459         xmlNodePtr nodeLevel1;
460         xmlNodePtr nodeLevel2;
461         xmlNodePtr nodeLevel3;
462         xmlNodePtr nodeLevel4;
463         xmlNodePtr nodeLevel5;
464         xmlNodePtr nodeLevel6;
465         
466         xmlNodePtr nodeStatusLv1;
467         xmlNodePtr nodeStatusLv2;
469         std::map<wxString,wxString> xmlDataMap;
470         std::map<wxString,wxString> ServerETagData;
472         wxString DataFilename;
473         wxString DataSyncToken;
474         int DataFileStatus;
475         wxString ETagData;
476         bool SyncTokenFound = FALSE;
478         std::string xmlStringSafe;
480         // Tranverse through the catacombs of the response to get our ETag for the file and
481         // the server syncronisation token.
483         // Start by getting all the server ETag data.
485         for (nodeLevel1 = xmlCardDAVDoc->children;
486                 nodeLevel1 != NULL;
487                 nodeLevel1 = nodeLevel1->next)
488         {
490                 for (nodeLevel2 = nodeLevel1->children;
491                         nodeLevel2 != NULL;
492                         nodeLevel2 = nodeLevel2->next)
493                 {
495                         for (nodeLevel3 = nodeLevel2->children;
496                         nodeLevel3 != NULL;
497                         nodeLevel3 = nodeLevel3->next)
498                         {
500                                 DataFileStatus = 0;
501                                 bool HREFFound = FALSE;
502                                 bool ETagFound = FALSE;
503                                 bool HTTPStatus = FALSE;
505                                 if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||
506                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||
507                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")
508                                 ){
510                                         // Get the filename.
511                                         
512                                         for (nodeLevel4 = nodeLevel3->children;
513                                         nodeLevel4 != NULL;
514                                         nodeLevel4 = nodeLevel4->next)
515                                         {
516                                         
517                                                 if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||
518                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||
519                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")
520                                                 ){
521                                                 
522                                                         DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);
523                                                         wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));
524                                                 
525                                                         while (wSTDFilename.HasMoreTokens()){
526                                                         
527                                                                 DataFilename = wSTDFilename.GetNextToken();
528                                                         
529                                                         }
530                                                         
531                                                         HREFFound = TRUE;
532                                                 
533                                                 }
534                                                 
535         
536                                         
537                                         }
538                                         
540                                 } else {
542                                         for (nodeLevel4 = nodeLevel3->children;
543                                         nodeLevel4 != NULL;
544                                         nodeLevel4 = nodeLevel4->next)
545                                         {
547                                                 for (nodeStatusLv1 = nodeLevel3->children;
548                                                         nodeStatusLv1 != NULL;
549                                                         nodeStatusLv1 = nodeStatusLv1->next)
550                                                 {
552                                                         if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){
553                 
554                                                                 DataFileStatus = 2;
555                                                                                 
556                                                                 HTTPStatus = TRUE;
557                                                                                 
558                                                         }
559                                         
560                                                         if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") ||
561                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") ||
562                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE)
563                                                         {
565                                                                 // Get the filename.
566                                         
567                                                                 for (nodeStatusLv2 = nodeStatusLv1->children;
568                                                                 nodeStatusLv2 != NULL;
569                                                                 nodeStatusLv2 = nodeStatusLv2->next)
570                                                                 {
571                                         
572                                                                         if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") ||
573                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") ||
574                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text")
575                                                                         ){
577                                                                                 if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){
578                                                                         
579                                                                                         DataFileStatus = 1;
580                                                                                         
581                                                                                         HTTPStatus = TRUE;
582                                                                         
583                                                                                 // This is currently in a WebDAV draft and may hopefully be enabled when this changes.
584                                                                         
585                                                                                 //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){
586                                                                                 
587                                                                                 //      DataFileStatus = 0;
588                                                                                 
589                                                                                 }
590                                                 
591                                                                         }
592                                                 
593         
594                                         
595                                                                 }
596                                                         
597                                                         }
599                                         
600                                                 }
601                                                 
602                                                 for (nodeLevel5 = nodeLevel4->children;
603                                                 nodeLevel5 != NULL;
604                                                 nodeLevel5 = nodeLevel5->next)
605                                                 {
607                                                         if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||
608                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||
609                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")
610                                                         ){
612                                                                 for (nodeLevel6 = nodeLevel5->children;
613                                                                 nodeLevel6 != NULL;
614                                                                 nodeLevel6 = nodeLevel6->next)
615                                                                 {
617                                                                         // Strip the quotes from the ETag.
618                                                 
619                                                                         ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);
620                                                                         if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){
621                                                 
622                                                                                 ETagData.Remove(0, 1);
623                                                                                 ETagData.RemoveLast();
624                                                 
625                                                                         }
626                                                                 
627                                                                         ETagFound = TRUE;
629                                                                 }
630                                                                 
631                                                         }
633                                                 }       
635                                         }
637                                 }
639                                 if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){
640                                 
641                                         // Add to the map data.
642                                         
643                                         FileSyncData SData;
644                                         
645                                         SData.ETagData = ETagData;
646                                         SData.DataFlag = DataFileStatus;
647                                         
648                                         ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));
649                                 
650                                 }
651                                 
652                                 // Reset the values.
653                                 
654                                 HREFFound = FALSE;
655                                 ETagFound = FALSE;
656                                 HTTPStatus = FALSE;
658                         }
660                         if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") ||
661                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") ||
662                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) &&
663                         SyncTokenFound == FALSE
664                         ){
666                                 for (nodeLevel3 = nodeLevel2->children;
667                                 nodeLevel3 != NULL;
668                                 nodeLevel3 = nodeLevel3->next)
669                                 {
671                                         if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") ||
672                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") ||
673                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text")
674                                         ){
675                         
676                                                 DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content);
678                                                 SyncTokenFound = TRUE;
679                         
680                                         }
681                         
682                                 }
683         
684                         }
686                 }
688         }
689         
690         for (nodeLevel1 = xmlCardDAVDoc->children;
691                 nodeLevel1 != NULL;
692                 nodeLevel1 = nodeLevel1->next)
693         {
695                 for (nodeLevel2 = nodeLevel1->children;
696                         nodeLevel2 != NULL;
697                         nodeLevel2 = nodeLevel2->next)
698                 {
700                         DataFileStatus = 0;
701                         bool HREFFound = FALSE;
702                         bool ETagFound = FALSE;
703                         bool HTTPStatus = FALSE;
705                         for (nodeLevel3 = nodeLevel2->children;
706                         nodeLevel3 != NULL;
707                         nodeLevel3 = nodeLevel3->next)
708                         {
710                                 if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||
711                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||
712                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")
713                                 ){
715                                         // Get the filename.
716                                         
717                                         for (nodeLevel4 = nodeLevel3->children;
718                                         nodeLevel4 != NULL;
719                                         nodeLevel4 = nodeLevel4->next)
720                                         {
721                                         
722                                                 if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||
723                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||
724                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")
725                                                 ){
726                                                 
727                                                         DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);
728                                                         wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));
729                                                 
730                                                         while (wSTDFilename.HasMoreTokens()){
731                                                         
732                                                                 DataFilename = wSTDFilename.GetNextToken();
733                                                         
734                                                         }
735                                                         
736                                                         HREFFound = TRUE;
737                                                 
738                                                 }
739                                                 
740         
741                                         
742                                         }
743                                         
745                                 } else {
747                                         for (nodeLevel4 = nodeLevel3->children;
748                                         nodeLevel4 != NULL;
749                                         nodeLevel4 = nodeLevel4->next)
750                                         {
752                                                 for (nodeStatusLv1 = nodeLevel3->children;
753                                                         nodeStatusLv1 != NULL;
754                                                         nodeStatusLv1 = nodeStatusLv1->next)
755                                                 {
757                                                         if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){
758                 
759                                                                 DataFileStatus = 2;
761                                                                 HTTPStatus = TRUE;
762                                                                                 
763                                                         }
764                                         
765                                                         if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") ||
766                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") ||
767                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE)
768                                                         {
770                                                                 // Get the filename.
771                                         
772                                                                 for (nodeStatusLv2 = nodeStatusLv1->children;
773                                                                 nodeStatusLv2 != NULL;
774                                                                 nodeStatusLv2 = nodeStatusLv2->next)
775                                                                 {
776                                         
777                                                                         if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") ||
778                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") ||
779                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text")
780                                                                         ){
782                                                                                 if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){
784                                                                                         DataFileStatus = 1;
785                                                                                         
786                                                                                         HTTPStatus = TRUE;
787                                                                         
788                                                                                 // This is currently in a WebDAV draft and may hopefully be enabled when this changes.
789                                                                         
790                                                                                 //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){
791                                                                                 
792                                                                                 //      DataFileStatus = 0;
793                                                                                 
794                                                                                 }
795                                                 
796                                                                         }
797                                                 
798         
799                                         
800                                                                 }
801                                                         
802                                                         }
804                                         
805                                                 }
806                                                 
807                                                 for (nodeLevel5 = nodeLevel4->children;
808                                                 nodeLevel5 != NULL;
809                                                 nodeLevel5 = nodeLevel5->next)
810                                                 {
812                                                         if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||
813                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||
814                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")
815                                                         ){
817                                                                 for (nodeLevel6 = nodeLevel5->children;
818                                                                 nodeLevel6 != NULL;
819                                                                 nodeLevel6 = nodeLevel6->next)
820                                                                 {
822                                                                         // Strip the quotes from the ETag.
823                                                 
824                                                                         ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);
825                                                                         if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){
826                                                 
827                                                                                 ETagData.Remove(0, 1);
828                                                                                 ETagData.RemoveLast();
829                                                 
830                                                                         }
831                                                                 
832                                                                         ETagFound = TRUE;
834                                                                 }
835                                                                 
836                                                         }
838                                                 }       
840                                         }
842                                 }
844                         }
846                         if (HREFFound == TRUE && HTTPStatus == TRUE && DataFileStatus == 2){
847                         
848                                 FileSyncData SData;
849                                         
850                                 SData.ETagData = wxT("");
851                                 SData.DataFlag = DataFileStatus;
852                                         
853                                 ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));                          
854                         
855                         }
857                         if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){
858                                 
859                                 // Add to the map data.
860                                         
861                                 FileSyncData SData;
862                                         
863                                 SData.ETagData = ETagData;
864                                 SData.DataFlag = DataFileStatus;
865                                         
866                                 ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));
867                                 
868                         }
869                                 
870                         // Reset the values.
871                                 
872                         HREFFound = FALSE;
873                         ETagFound = FALSE;
874                         HTTPStatus = FALSE;
875                         DataFilename.Clear();
877                         if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") ||
878                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") ||
879                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) &&
880                         SyncTokenFound == FALSE
881                         ){
883                                 for (nodeLevel3 = nodeLevel2->children;
884                                 nodeLevel3 != NULL;
885                                 nodeLevel3 = nodeLevel3->next)
886                                 {
888                                         if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") ||
889                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") ||
890                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text")
891                                         ){
892                         
893                                                 DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content);
895                                                 SyncTokenFound = TRUE;
896                         
897                                         }
898                         
899                                 }
900         
901                         }
903                 }
905         }
906         
907         // Get the sync token.
908         
909         if (SyncTokenFound == TRUE){
910         
911                 ContactListFinal.SyncToken = DataSyncToken;
912         
913         } else {
914         
915         }
917         SleepFor(2000000000);
919         xmlFreeDoc(xmlCardDAVDoc);
920         curl_easy_cleanup(conn);
922         SyncDataBuffer.reset();
924         // Get the first result.
926         return ContactListFinal;
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