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