Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
16acdb5aaf30c4f88e6f4a3fcc2237b64cbb7eba
[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();
52         
53         struct CardDAVCURLPasser {
54         
55                 CardDAV *Data;
56                 bool HeaderMode = TRUE;
57         
58         } CardDAVHeader, CardDAVFooter;
60         CardDAVHeader.Data = this;
61         CardDAVHeader.HeaderMode = TRUE;
62         
63         CardDAVFooter.Data = this;
64         CardDAVFooter.HeaderMode = FALSE;
66         wxString Data1;
67         wxString Data2;
68         
69         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + wxT("/");
70         ServerAddressSSL = wxT("https://") + ServerAddressURL;
71         ServerAddressNormal = wxT("http://") + ServerAddressURL;
72         
73         ServerAuth = ServerUser + wxT(":") + ServerPass;
74         
75         // Load the sync token file (if it exists).
76         
77         wxCharBuffer SyncDataBuffer;
78         wxString SyncData;
79         
80         SyncData.Clear();
81         
82         SyncTokenInc.Trim();
83         
84         if (!SyncTokenInc.IsEmpty()){
85                 
86                 SyncData = wxT("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
87                 SyncData.Append(wxT("<D:sync-collection xmlns:D=\"DAV:\"\n"));
88                 SyncData.Append(wxT(" xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"));
89                 SyncData.Append(wxT("<D:sync-token>"));
90                 SyncData.Append(SyncTokenInc);
91                 SyncData.Append(wxT("</D:sync-token>\n"));
92                 SyncData.Append(wxT("<D:sync-level>1</D:sync-level>\n"));
93                 SyncData.Append(wxT("<D:prop>\n"));
94                 SyncData.Append(wxT("   <D:getetag/>\n"));
95                 SyncData.Append(wxT("</D:prop>\n"));
96                 SyncData.Append(wxT("</D:sync-collection>"));
97                 
98                 SyncDataBuffer = SyncData.ToUTF8();
99         
100         } else {
101                 
102                 SyncData = wxT("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
103                 SyncData.Append(wxT("<D:sync-collection xmlns:D=\"DAV:\""));
104                 SyncData.Append(wxT(" xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"));
105                 SyncData.Append(wxT("<D:sync-token/>\n"));
106                 SyncData.Append(wxT("<D:sync-level>1</D:sync-level>\n"));
107                 SyncData.Append(wxT("<D:prop>\n"));
108                 SyncData.Append(wxT("   <D:getetag/>\n"));
109                 SyncData.Append(wxT("</D:prop>\n"));
110                 SyncData.Append(wxT("</D:sync-collection>\n"));
111                 
112                 SyncDataBuffer = SyncData.ToUTF8();
114         }
116         const char* query = SyncDataBuffer.data();
117         
118         // Try SSL first.
120         std::map<int,int>::iterator ActIter;
121         struct UploadDataStruc UploadData;
122         
123         ActIter = ActivityListPtr->find((int)ItemIndex);
125         curl_slist *slist = NULL;       
127         slist = curl_slist_append(slist, "Depth: 1");
129         if (ServerSSL){
131                 wxString ServerCertFilename;
132                 bool MatchingCert = FALSE;
134                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
135                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
136                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
137                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
138                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
139                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
140                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
141                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
142                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
143                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
144                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
145                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
146                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
147                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
148                 curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
149                 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
151                 ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
153                 if (wxFile::Exists(ServerCertFilename) == TRUE){
154                 
155                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
156                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
157                         curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
158                 
159                 }
161                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
162                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
164                 claconncode = (curl_easy_perform(conn));
166                 // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without
167                 // the local certificate in use.
169                 if (claconncode == CURLE_PEER_FAILED_VERIFICATION){
170                         
171                         curl_easy_cleanup(conn);
172                         conn = curl_easy_init();
173                         
174                         curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
175                         curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
176                         curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
177                         curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
178                         curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
179                         curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
180                         curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
181                         curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
182                         curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
183                         curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
184                         curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
185                         curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
186                         curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
187                         curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
188                         curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
189                         curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
190                         curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
191                         curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
192                         
193                         claconncode = (curl_easy_perform(conn));
194                         
195                         // If claconncode is CURLE_OK then delete the certificate file as that
196                         // is no longer needed.
197                         
198                         if (claconncode == CURLE_OK){
199                         
200                                 // Delete the certificate file.
201                                 
202                                 wxRemoveFile(ServerCertFilename);
203                         
204                         }
205                 
206                 }
208                 // Check if it fails with a CURLE_SSL_CACERT then compare
209                 // the certificates as PEM files.
210                 
211                 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
213                         CURL *sslerrconn;
214                         sslerrconn = curl_easy_init();
215                         CURLcode sslerrconncode;
216                         
217                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
219                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
220                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
221                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
222                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
223                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
224                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
225                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
226                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
227                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
228                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
229                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
230                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
231                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
232                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
233                 
234                         wxString SSLLocalData;
235                         wxString SSLServerData;
236                 
237                         sslerrconncode = (curl_easy_perform(sslerrconn));
238                 
239                         SSLCertCol = BuildSSLCollection(sslerrconn);
240                         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);
241                         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
242                         
243                         wxFFile SSLLocalFile;
244                         
245 #if wxABI_VERSION < 20900
246                         SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
247 #else
248                         SSLLocalFile.Open(ServerCertFilename, wxT("r"));
249 #endif  
250         
251                         // Load the recovery database for tasks not done.
252         
253                         if (SSLLocalFile.IsOpened() == TRUE){
255                         // Check if we are using wxWidgets version 2.8 or less and
256                         // execute the required command accordingly.
257         
258                                 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
259                 
260         
261                         }
262                         
263                         SSLServerData = SSLDataIter->second;
264                         
265                         if (SSLLocalData == SSLServerData){
266                         
267                                 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
268                                 // and CURLOPT_SSL_VERIFYHOST off.
269                         
270                                 curl_easy_cleanup(conn);
271                                 conn = curl_easy_init();
272                                 
273                                 PageHeader.clear();
274                                 PageData.clear();
275                                 
276                                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
277                                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
278                                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
279                                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
280                                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
281                                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
282                                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
283                                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
284                                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
285                                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
286                                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
287                                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
288                                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
289                                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
290                                 curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
291                                 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
292                                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
293                                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
294                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);
295                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);
296                         
297                                 claconncode = (curl_easy_perform(conn));
298                                 
299                                 MatchingCert = TRUE;
300                         
301                         }
302                         
303                         if (MatchingCert == FALSE){
304                 
305                                 claconncode = CURLE_SSL_CACERT;
306                                 return ContactListFinal;
307                 
308                         }
309                         
310                         curl_easy_cleanup(sslerrconn);
311                 
312                 }
314                 // Sort out SSL error.
315                 
316                 // When SSL cert error occurs, connect again and fetch certificates.
317                 // Display a message to the user explaining that an invalid
318                 // certificate has been given and let the user decide what
319                 // to do next.
321                 if (claconncode == CURLE_OK){
323                 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
324                 
325                         CURL *sslerrconn;
326                         sslerrconn = curl_easy_init();
327                         CURLcode sslerrconncode;
328                 
329                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
330                 
331                         // Replace conn with sslerrconn!
332                 
333                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
334                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
335                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
336                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
337                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
338                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
339                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
340                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
341                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
342                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
343                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
344                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
345                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
346                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
347                 
348                         sslerrconncode = (curl_easy_perform(sslerrconn));
350                         SSLCertCol = BuildSSLCollection(sslerrconn);
351                         SSLCertCol.SuccessCode = 1;
353                         return ContactListFinal;
354                 
355                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
356                 
357                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
358                                         curl_easy_strerror(claconncode));
359                         int http_code = 0;
360                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
361                         fprintf(stderr, "Error code was: %d\n", http_code);
362                                         
363                         return ContactListFinal;
364                 
365                 } else {
367                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
368                                         curl_easy_strerror(claconncode));
369                         int http_code = 0;
370                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
371                         fprintf(stderr, "Error code was: %d\n", http_code);
373                         return ContactListFinal;
375                 }
377                 SSLCertCol = BuildSSLCollection(conn);
379         } else {
380         
381         // No SSL.
382                 
383                 wxString EmptyString;
384                 
385                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
386                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
387                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
388                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
389                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
390                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
391                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
392                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
393                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
394                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
395                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
396                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
397                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
398                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
399                 curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
400                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
401                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));           
402                 
403                 PageData.Clear();
404                 PageHeader.Clear();
405                 
406                 claconncode = (curl_easy_perform(conn));
408                 if (claconncode == CURLE_OK){
412                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
413                 
414                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
415                                         curl_easy_strerror(claconncode));
416                         int http_code = 0;
417                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
418                         fprintf(stderr, "Error code was: %i\n", http_code);
419                                         
420                         return ContactListFinal;
421                         
422                 } else {
424                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
425                                         curl_easy_strerror(claconncode));
426                         int http_code = 0;
427                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
428                         fprintf(stderr, "Error code was: %i\n", http_code);
429                                 
430                         return ContactListFinal;
432                 }
433                 
434         }
436         xmlDocPtr xmlCardDAVDoc;
437         xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);
439         xmlNodePtr nodeLevel1;
440         xmlNodePtr nodeLevel2;
441         xmlNodePtr nodeLevel3;
442         xmlNodePtr nodeLevel4;
443         xmlNodePtr nodeLevel5;
444         xmlNodePtr nodeLevel6;
445         
446         xmlNodePtr nodeStatusLv1;
447         xmlNodePtr nodeStatusLv2;
449         std::map<wxString,wxString> xmlDataMap;
450         std::map<wxString,wxString> ServerETagData;
452         wxString DataFilename;
453         wxString DataSyncToken;
454         int DataFileStatus;
455         wxString ETagData;
456         bool SyncTokenFound = FALSE;
458         std::string xmlStringSafe;
460         // Tranverse through the catacombs of the response to get our ETag for the file and
461         // the server syncronisation token.
463         // Start by getting all the server ETag data.
465         for (nodeLevel1 = xmlCardDAVDoc->children;
466                 nodeLevel1 != NULL;
467                 nodeLevel1 = nodeLevel1->next)
468         {
470                 for (nodeLevel2 = nodeLevel1->children;
471                         nodeLevel2 != NULL;
472                         nodeLevel2 = nodeLevel2->next)
473                 {
475                         for (nodeLevel3 = nodeLevel2->children;
476                         nodeLevel3 != NULL;
477                         nodeLevel3 = nodeLevel3->next)
478                         {
480                                 DataFileStatus = 0;
481                                 bool HREFFound = FALSE;
482                                 bool ETagFound = FALSE;
483                                 bool HTTPStatus = FALSE;
485                                 if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||
486                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||
487                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")
488                                 ){
490                                         // Get the filename.
491                                         
492                                         for (nodeLevel4 = nodeLevel3->children;
493                                         nodeLevel4 != NULL;
494                                         nodeLevel4 = nodeLevel4->next)
495                                         {
496                                         
497                                                 if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||
498                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||
499                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")
500                                                 ){
501                                                 
502                                                         DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);
503                                                         wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));
504                                                 
505                                                         while (wSTDFilename.HasMoreTokens()){
506                                                         
507                                                                 DataFilename = wSTDFilename.GetNextToken();
508                                                         
509                                                         }
510                                                         
511                                                         HREFFound = TRUE;
512                                                 
513                                                 }
514                                                 
515         
516                                         
517                                         }
518                                         
520                                 } else {
522                                         for (nodeLevel4 = nodeLevel3->children;
523                                         nodeLevel4 != NULL;
524                                         nodeLevel4 = nodeLevel4->next)
525                                         {
527                                                 for (nodeStatusLv1 = nodeLevel3->children;
528                                                         nodeStatusLv1 != NULL;
529                                                         nodeStatusLv1 = nodeStatusLv1->next)
530                                                 {
532                                                         if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){
533                 
534                                                                 DataFileStatus = 2;
535                                                                                 
536                                                                 HTTPStatus = TRUE;
537                                                                                 
538                                                         }
539                                         
540                                                         if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") ||
541                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") ||
542                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE)
543                                                         {
545                                                                 // Get the filename.
546                                         
547                                                                 for (nodeStatusLv2 = nodeStatusLv1->children;
548                                                                 nodeStatusLv2 != NULL;
549                                                                 nodeStatusLv2 = nodeStatusLv2->next)
550                                                                 {
551                                         
552                                                                         if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") ||
553                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") ||
554                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text")
555                                                                         ){
557                                                                                 if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){
558                                                                         
559                                                                                         DataFileStatus = 1;
560                                                                                         
561                                                                                         HTTPStatus = TRUE;
562                                                                         
563                                                                                 // This is currently in a WebDAV draft and may hopefully be enabled when this changes.
564                                                                         
565                                                                                 //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){
566                                                                                 
567                                                                                 //      DataFileStatus = 0;
568                                                                                 
569                                                                                 }
570                                                 
571                                                                         }
572                                                 
573         
574                                         
575                                                                 }
576                                                         
577                                                         }
579                                         
580                                                 }
581                                                 
582                                                 for (nodeLevel5 = nodeLevel4->children;
583                                                 nodeLevel5 != NULL;
584                                                 nodeLevel5 = nodeLevel5->next)
585                                                 {
587                                                         if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||
588                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||
589                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")
590                                                         ){
592                                                                 for (nodeLevel6 = nodeLevel5->children;
593                                                                 nodeLevel6 != NULL;
594                                                                 nodeLevel6 = nodeLevel6->next)
595                                                                 {
597                                                                         // Strip the quotes from the ETag.
598                                                 
599                                                                         ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);
600                                                                         if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){
601                                                 
602                                                                                 ETagData.Remove(0, 1);
603                                                                                 ETagData.RemoveLast();
604                                                 
605                                                                         }
606                                                                 
607                                                                         ETagFound = TRUE;
609                                                                 }
610                                                                 
611                                                         }
613                                                 }       
615                                         }
617                                 }
619                                 if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){
620                                 
621                                         // Add to the map data.
622                                         
623                                         FileSyncData SData;
624                                         
625                                         SData.ETagData = ETagData;
626                                         SData.DataFlag = DataFileStatus;
627                                         
628                                         ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));
629                                 
630                                 }
631                                 
632                                 // Reset the values.
633                                 
634                                 HREFFound = FALSE;
635                                 ETagFound = FALSE;
636                                 HTTPStatus = FALSE;
638                         }
640                         if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") ||
641                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") ||
642                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) &&
643                         SyncTokenFound == FALSE
644                         ){
646                                 for (nodeLevel3 = nodeLevel2->children;
647                                 nodeLevel3 != NULL;
648                                 nodeLevel3 = nodeLevel3->next)
649                                 {
651                                         if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") ||
652                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") ||
653                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text")
654                                         ){
655                         
656                                                 DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content);
658                                                 SyncTokenFound = TRUE;
659                         
660                                         }
661                         
662                                 }
663         
664                         }
666                 }
668         }
669         
670         for (nodeLevel1 = xmlCardDAVDoc->children;
671                 nodeLevel1 != NULL;
672                 nodeLevel1 = nodeLevel1->next)
673         {
675                 for (nodeLevel2 = nodeLevel1->children;
676                         nodeLevel2 != NULL;
677                         nodeLevel2 = nodeLevel2->next)
678                 {
680                         DataFileStatus = 0;
681                         bool HREFFound = FALSE;
682                         bool ETagFound = FALSE;
683                         bool HTTPStatus = FALSE;
685                         for (nodeLevel3 = nodeLevel2->children;
686                         nodeLevel3 != NULL;
687                         nodeLevel3 = nodeLevel3->next)
688                         {
690                                 if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||
691                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||
692                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")
693                                 ){
695                                         // Get the filename.
696                                         
697                                         for (nodeLevel4 = nodeLevel3->children;
698                                         nodeLevel4 != NULL;
699                                         nodeLevel4 = nodeLevel4->next)
700                                         {
701                                         
702                                                 if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||
703                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||
704                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")
705                                                 ){
706                                                 
707                                                         DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);
708                                                         wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));
709                                                 
710                                                         while (wSTDFilename.HasMoreTokens()){
711                                                         
712                                                                 DataFilename = wSTDFilename.GetNextToken();
713                                                         
714                                                         }
715                                                         
716                                                         HREFFound = TRUE;
717                                                 
718                                                 }
719                                                 
720         
721                                         
722                                         }
723                                         
725                                 } else {
727                                         for (nodeLevel4 = nodeLevel3->children;
728                                         nodeLevel4 != NULL;
729                                         nodeLevel4 = nodeLevel4->next)
730                                         {
732                                                 for (nodeStatusLv1 = nodeLevel3->children;
733                                                         nodeStatusLv1 != NULL;
734                                                         nodeStatusLv1 = nodeStatusLv1->next)
735                                                 {
737                                                         if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){
738                 
739                                                                 DataFileStatus = 2;
741                                                                 HTTPStatus = TRUE;
742                                                                                 
743                                                         }
744                                         
745                                                         if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") ||
746                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") ||
747                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE)
748                                                         {
750                                                                 // Get the filename.
751                                         
752                                                                 for (nodeStatusLv2 = nodeStatusLv1->children;
753                                                                 nodeStatusLv2 != NULL;
754                                                                 nodeStatusLv2 = nodeStatusLv2->next)
755                                                                 {
756                                         
757                                                                         if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") ||
758                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") ||
759                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text")
760                                                                         ){
762                                                                                 if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){
764                                                                                         DataFileStatus = 1;
765                                                                                         
766                                                                                         HTTPStatus = TRUE;
767                                                                         
768                                                                                 // This is currently in a WebDAV draft and may hopefully be enabled when this changes.
769                                                                         
770                                                                                 //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){
771                                                                                 
772                                                                                 //      DataFileStatus = 0;
773                                                                                 
774                                                                                 }
775                                                 
776                                                                         }
777                                                 
778         
779                                         
780                                                                 }
781                                                         
782                                                         }
784                                         
785                                                 }
786                                                 
787                                                 for (nodeLevel5 = nodeLevel4->children;
788                                                 nodeLevel5 != NULL;
789                                                 nodeLevel5 = nodeLevel5->next)
790                                                 {
792                                                         if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||
793                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||
794                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")
795                                                         ){
797                                                                 for (nodeLevel6 = nodeLevel5->children;
798                                                                 nodeLevel6 != NULL;
799                                                                 nodeLevel6 = nodeLevel6->next)
800                                                                 {
802                                                                         // Strip the quotes from the ETag.
803                                                 
804                                                                         ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);
805                                                                         if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){
806                                                 
807                                                                                 ETagData.Remove(0, 1);
808                                                                                 ETagData.RemoveLast();
809                                                 
810                                                                         }
811                                                                 
812                                                                         ETagFound = TRUE;
814                                                                 }
815                                                                 
816                                                         }
818                                                 }       
820                                         }
822                                 }
824                         }
826                         if (HREFFound == TRUE && HTTPStatus == TRUE && DataFileStatus == 2){
827                         
828                                 FileSyncData SData;
829                                         
830                                 SData.ETagData = wxT("");
831                                 SData.DataFlag = DataFileStatus;
832                                         
833                                 ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));                          
834                         
835                         }
837                         if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){
838                                 
839                                 // Add to the map data.
840                                         
841                                 FileSyncData SData;
842                                         
843                                 SData.ETagData = ETagData;
844                                 SData.DataFlag = DataFileStatus;
845                                         
846                                 ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));
847                                 
848                         }
849                                 
850                         // Reset the values.
851                                 
852                         HREFFound = FALSE;
853                         ETagFound = FALSE;
854                         HTTPStatus = FALSE;
855                         DataFilename.Clear();
857                         if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") ||
858                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") ||
859                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) &&
860                         SyncTokenFound == FALSE
861                         ){
863                                 for (nodeLevel3 = nodeLevel2->children;
864                                 nodeLevel3 != NULL;
865                                 nodeLevel3 = nodeLevel3->next)
866                                 {
868                                         if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") ||
869                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") ||
870                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text")
871                                         ){
872                         
873                                                 DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content);
875                                                 SyncTokenFound = TRUE;
876                         
877                                         }
878                         
879                                 }
880         
881                         }
883                 }
885         }
886         
887         // Get the sync token.
888         
889         if (SyncTokenFound == TRUE){
890         
891                 ContactListFinal.SyncToken = DataSyncToken;
892         
893         } else {
894         
895         }
897         SleepFor(2000000000);
899         xmlFreeDoc(xmlCardDAVDoc);
900         curl_easy_cleanup(conn);
902         SyncDataBuffer.reset();
904         // Get the first result.
906         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