Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Added copyright and license headers on C++ source and header files in the carddav...
[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         ContactListData ContactListFinal;
34         std::map<wxString,FileSyncData> ContactList;
35         
36         PageData.Clear();
37         PageHeader.Clear();
39         SSLStatus = TRUE;
40         AuthPassed = TRUE;
41         AbortConnection = FALSE;
43         CURL *conn;
44         wxString ServerAddressURL;
45         wxString ServerAuth;
46         wxString ServerAddressSSL;
47         wxString ServerAddressNormal;
49         conn = curl_easy_init();
50         
51         struct CardDAVCURLPasser {
52         
53                 CardDAV *Data;
54                 bool HeaderMode = TRUE;
55         
56         } CardDAVHeader, CardDAVFooter;
58         CardDAVHeader.Data = this;
59         CardDAVHeader.HeaderMode = TRUE;
60         
61         CardDAVFooter.Data = this;
62         CardDAVFooter.HeaderMode = FALSE;
64         wxString Data1;
65         wxString Data2;
66         
67         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/") + ServerPrefix + wxT("/");
68         ServerAddressSSL = wxT("https://") + ServerAddressURL;
69         ServerAddressNormal = wxT("http://") + ServerAddressURL;
70         
71         ServerAuth = ServerUser + wxT(":") + ServerPass;
72         
73         // Load the sync token file (if it exists).
74         
75         wxCharBuffer SyncDataBuffer;
76         wxString SyncData;
77         
78         SyncData.Clear();
79         
80         SyncTokenInc.Trim();
81         
82         if (!SyncTokenInc.IsEmpty()){
83                 
84                 SyncData = wxT("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
85                 SyncData.Append(wxT("<D:sync-collection xmlns:D=\"DAV:\"\n"));
86                 SyncData.Append(wxT(" xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"));
87                 SyncData.Append(wxT("<D:sync-token>"));
88                 //SyncData.Trim();
89                 //SyncData.Append(wxT("data:,00378c55-1f44-44a2-a255-84f6560b5cac_580"));
90                 SyncData.Append(SyncTokenInc);
91                 //SyncData.Trim();
92                 SyncData.Append(wxT("</D:sync-token>\n"));
93                 SyncData.Append(wxT("<D:sync-level>1</D:sync-level>\n"));
94                 SyncData.Append(wxT("<D:prop>\n"));
95                 SyncData.Append(wxT("   <D:getetag/>\n"));
96                 SyncData.Append(wxT("</D:prop>\n"));
97                 SyncData.Append(wxT("</D:sync-collection>"));
98                 
99                 SyncDataBuffer = SyncData.ToUTF8();
100         
101         } else {
102                 
103                 SyncData = wxT("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
104                 SyncData.Append(wxT("<D:sync-collection xmlns:D=\"DAV:\""));
105                 SyncData.Append(wxT(" xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"));
106                 SyncData.Append(wxT("<D:sync-token/>\n"));
107                 SyncData.Append(wxT("<D:sync-level>1</D:sync-level>\n"));
108                 SyncData.Append(wxT("<D:prop>\n"));
109                 SyncData.Append(wxT("   <D:getetag/>\n"));
110                 SyncData.Append(wxT("</D:prop>\n"));
111                 SyncData.Append(wxT("</D:sync-collection>\n"));
112                 
113                 SyncDataBuffer = SyncData.ToUTF8();
115         }
116         
117         //static const char* query = SyncData.mb_str();
118         
119         /*char *query = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\
120                 <D:sync-collection xmlns:D=\"DAV:\"\n\
121                  xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n\
122                 <D:sync-token>data:,00378c55-1f44-44a2-a255-84f6560b5cac_580</D:sync-token>\n\
123                 <D:sync-level>1</D:sync-level>\n\
124                 <D:prop>\n\
125                         <D:getetag/>\n\
126                 </D:prop>\n\
127         </D:sync-collection>\n";*/
128         const char* query = SyncDataBuffer.data();
129         
130         // Try SSL first.
132         std::map<int,int>::iterator ActIter;
133         struct UploadDataStruc UploadData;
134         
135         ActIter = ActivityListPtr->find((int)ItemIndex);
137         curl_slist *slist = NULL;       
139         slist = curl_slist_append(slist, "Depth: 1");
141         if (ServerSSL){
143                 wxString ServerCertFilename;
144                 bool MatchingCert = FALSE;
146                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
147                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
148                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
149                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
150                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
151                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
152                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
153                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
154                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
155                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
156                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
157                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
158                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
159                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
160                 curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
161                 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
163                 ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
165                 if (wxFile::Exists(ServerCertFilename) == TRUE){
166                 
167                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
168                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
169                         curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
170                 
171                 }
173                 //UploadData.readptr = &CardDAVDataQuery;
174                 //UploadData.sizeleft = CardDAVDataQuery.Len();
175                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
176                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
177                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
178                 
179                 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);
180                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
181                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
183                 claconncode = (curl_easy_perform(conn));
185                 // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without
186                 // the local certificate in use.
188                 if (claconncode == CURLE_PEER_FAILED_VERIFICATION){
189                         
190                         curl_easy_cleanup(conn);
191                         conn = curl_easy_init();
192                         
193                         curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
194                         curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
195                         curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
196                         curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
197                         curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
198                         curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
199                         curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
200                         curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
201                         curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
202                         curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
203                         curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
204                         curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
205                         curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
206                         curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
207                         curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
208                         curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
209                         curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
210                         curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
211                         
212                         claconncode = (curl_easy_perform(conn));
213                         
214                         // If claconncode is CURLE_OK then delete the certificate file as that
215                         // is no longer needed.
216                         
217                         if (claconncode == CURLE_OK){
218                         
219                                 // Delete the certificate file.
220                                 
221                                 wxRemoveFile(ServerCertFilename);
222                         
223                         }
224                 
225                 }
227                 // Check if it fails with a CURLE_SSL_CACERT then compare
228                 // the certificates as PEM files.
229                 
230                 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
231                 
232                         //curl_easy_cleanup(conn);
233                         //conn = curl_easy_init();
235                         CURL *sslerrconn;
236                         sslerrconn = curl_easy_init();
237                         CURLcode sslerrconncode;
239                         //claconncode = (curl_easy_perform(conn));
241                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
243                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
244                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
245                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
246                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
247                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
248                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
249                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
250                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
251                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
252                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
253                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
254                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
255                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
256                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
257                 
258                         wxString SSLLocalData;
259                         wxString SSLServerData;
260                 
261                         sslerrconncode = (curl_easy_perform(sslerrconn));
262                 
263                         SSLCertCol = BuildSSLCollection(sslerrconn);
264                         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);
265                         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
266                         
267                         wxFFile SSLLocalFile;
268                         
269 #if wxABI_VERSION < 20900
270                         SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
271 #else
272                         SSLLocalFile.Open(ServerCertFilename, wxT("r"));
273 #endif  
274         
275                         // Load the recovery database for tasks not done.
276         
277                         if (SSLLocalFile.IsOpened() == TRUE){
279                         // Check if we are using wxWidgets version 2.8 or less and
280                         // execute the required command accordingly.
281         
282                                 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
283                 
284         
285                         }
286                         
287                         SSLServerData = SSLDataIter->second;
288                         
289                         if (SSLLocalData == SSLServerData){
290                         
291                                 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
292                                 // and CURLOPT_SSL_VERIFYHOST off.
293                         
294                                 curl_easy_cleanup(conn);
295                                 conn = curl_easy_init();
296                                 
297                                 PageHeader.clear();
298                                 PageData.clear();
299                                 
300                                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
301                                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
302                                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
303                                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
304                                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
305                                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
306                                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
307                                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
308                                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
309                                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
310                                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
311                                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
312                                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
313                                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
314                                 curl_easy_setopt(conn, CURLOPT_HTTPHEADER, slist);
315                                 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
316                                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
317                                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
318                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);
319                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);
320                         
321                                 claconncode = (curl_easy_perform(conn));
322                                 
323                                 MatchingCert = TRUE;
324                         
325                         }
326                         
327                         if (MatchingCert == FALSE){
328                 
329                                 claconncode = CURLE_SSL_CACERT;
330                                 return ContactListFinal;
331                 
332                         }
333                         
334                         curl_easy_cleanup(sslerrconn);
335                 
336                 }
338                 // Sort out SSL error.
339                 
340                 // When SSL cert error occurs, connect again and fetch certificates.
341                 // Display a message to the user explaining that an invalid
342                 // certificate has been given and let the user decide what
343                 // to do next.
345                 if (claconncode == CURLE_OK){
347                 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
348                 
349                         CURL *sslerrconn;
350                         sslerrconn = curl_easy_init();
351                         CURLcode sslerrconncode;
352                 
353                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
354                 
355                         // Replace conn with sslerrconn!
356                 
357                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
358                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
359                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
360                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
361                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
362                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
363                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
364                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
365                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
366                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
367                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
368                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
369                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
370                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
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);
425                 //UploadData.readptr = &CardDAVDataQuery;
426                 //UploadData.sizeleft = CardDAVDataQuery.Len();
427                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
428                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
429                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
430                 
431                 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);
432                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
433                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));           
434                 
435                 PageData.Clear();
436                 PageHeader.Clear();
437                 
438                 claconncode = (curl_easy_perform(conn));
440                 if (claconncode == CURLE_OK){
444                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
445                 
446                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
447                                         curl_easy_strerror(claconncode));
448                         int http_code = 0;
449                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
450                         fprintf(stderr, "Error code was: %i\n", http_code);
451                                         
452                         return ContactListFinal;
453                         
454                 } else {
456                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
457                                         curl_easy_strerror(claconncode));
458                         int http_code = 0;
459                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
460                         fprintf(stderr, "Error code was: %i\n", http_code);
461                                 
462                         return ContactListFinal;
464                 }
465                 
466         }
468         xmlDocPtr xmlCardDAVDoc;
469         xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);
471         xmlNodePtr nodeLevel1;
472         xmlNodePtr nodeLevel2;
473         xmlNodePtr nodeLevel3;
474         xmlNodePtr nodeLevel4;
475         xmlNodePtr nodeLevel5;
476         xmlNodePtr nodeLevel6;
477         
478         xmlNodePtr nodeStatusLv1;
479         xmlNodePtr nodeStatusLv2;
481         std::map<wxString,wxString> xmlDataMap;
482         std::map<wxString,wxString> ServerETagData;
484         wxString DataFilename;
485         wxString DataSyncToken;
486         int DataFileStatus;
487         wxString ETagData;
488         bool SyncTokenFound = FALSE;
490         std::string xmlStringSafe;
492         // Tranverse through the catacombs of the response to get our ETag for the file and
493         // the server syncronisation token.
495         // Start by getting all the server ETag data.
497         for (nodeLevel1 = xmlCardDAVDoc->children;
498                 nodeLevel1 != NULL;
499                 nodeLevel1 = nodeLevel1->next)
500         {
502                 for (nodeLevel2 = nodeLevel1->children;
503                         nodeLevel2 != NULL;
504                         nodeLevel2 = nodeLevel2->next)
505                 {
507                         for (nodeLevel3 = nodeLevel2->children;
508                         nodeLevel3 != NULL;
509                         nodeLevel3 = nodeLevel3->next)
510                         {
512                                 DataFileStatus = 0;
513                                 bool HREFFound = FALSE;
514                                 bool ETagFound = FALSE;
515                                 bool HTTPStatus = FALSE;
517                                 if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||
518                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||
519                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")
520                                 ){
522                                         // Get the filename.
523                                         
524                                         for (nodeLevel4 = nodeLevel3->children;
525                                         nodeLevel4 != NULL;
526                                         nodeLevel4 = nodeLevel4->next)
527                                         {
528                                         
529                                                 if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||
530                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||
531                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")
532                                                 ){
533                                                 
534                                                         DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);
535                                                         wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));
536                                                 
537                                                         while (wSTDFilename.HasMoreTokens()){
538                                                         
539                                                                 DataFilename = wSTDFilename.GetNextToken();
540                                                         
541                                                         }
542                                                         
543                                                         HREFFound = TRUE;
544                                                 
545                                                 }
546                                                 
547         
548                                         
549                                         }
550                                         
552                                 } else {
554                                         for (nodeLevel4 = nodeLevel3->children;
555                                         nodeLevel4 != NULL;
556                                         nodeLevel4 = nodeLevel4->next)
557                                         {
559                                                 for (nodeStatusLv1 = nodeLevel3->children;
560                                                         nodeStatusLv1 != NULL;
561                                                         nodeStatusLv1 = nodeStatusLv1->next)
562                                                 {
564                                                         if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){
565                 
566                                                                 DataFileStatus = 2;
567                                                                                 
568                                                                 HTTPStatus = TRUE;
569                                                                                 
570                                                         }
571                                         
572                                                         if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") ||
573                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") ||
574                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE)
575                                                         {
577                                                                 // Get the filename.
578                                         
579                                                                 for (nodeStatusLv2 = nodeStatusLv1->children;
580                                                                 nodeStatusLv2 != NULL;
581                                                                 nodeStatusLv2 = nodeStatusLv2->next)
582                                                                 {
583                                         
584                                                                         if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") ||
585                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") ||
586                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text")
587                                                                         ){
589                                                                                 if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){
590                                                                         
591                                                                                         DataFileStatus = 1;
592                                                                                         
593                                                                                         HTTPStatus = TRUE;
594                                                                         
595                                                                                 // This is currently in a WebDAV draft and may hopefully be enabled when this changes.
596                                                                         
597                                                                                 //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){
598                                                                                 
599                                                                                 //      DataFileStatus = 0;
600                                                                                 
601                                                                                 }
602                                                 
603                                                                         }
604                                                 
605         
606                                         
607                                                                 }
608                                                         
609                                                         }
611                                         
612                                                 }
613                                                 
614                                                 for (nodeLevel5 = nodeLevel4->children;
615                                                 nodeLevel5 != NULL;
616                                                 nodeLevel5 = nodeLevel5->next)
617                                                 {
619                                                         if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||
620                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||
621                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")
622                                                         ){
624                                                                 for (nodeLevel6 = nodeLevel5->children;
625                                                                 nodeLevel6 != NULL;
626                                                                 nodeLevel6 = nodeLevel6->next)
627                                                                 {
629                                                                         // Strip the quotes from the ETag.
630                                                 
631                                                                         ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);
632                                                                         if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){
633                                                 
634                                                                                 ETagData.Remove(0, 1);
635                                                                                 ETagData.RemoveLast();
636                                                 
637                                                                         }
638                                                                 
639                                                                         ETagFound = TRUE;
641                                                                 }
642                                                                 
643                                                         }
645                                                 }       
647                                         }
649                                 }
651                                 if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){
652                                 
653                                         // Add to the map data.
654                                         
655                                         FileSyncData SData;
656                                         
657                                         SData.ETagData = ETagData;
658                                         SData.DataFlag = DataFileStatus;
659                                         
660                                         ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));
661                                 
662                                 }
663                                 
664                                 // Reset the values.
665                                 
666                                 HREFFound = FALSE;
667                                 ETagFound = FALSE;
668                                 HTTPStatus = FALSE;
670                         }
672                         if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") ||
673                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") ||
674                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) &&
675                         SyncTokenFound == FALSE
676                         ){
678                                 for (nodeLevel3 = nodeLevel2->children;
679                                 nodeLevel3 != NULL;
680                                 nodeLevel3 = nodeLevel3->next)
681                                 {
683                                         if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") ||
684                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") ||
685                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text")
686                                         ){
687                         
688                                                 DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content);
690                                                 SyncTokenFound = TRUE;
691                         
692                                         }
693                         
694                                 }
695         
696                         }
698                 }
700         }
701         
702         for (nodeLevel1 = xmlCardDAVDoc->children;
703                 nodeLevel1 != NULL;
704                 nodeLevel1 = nodeLevel1->next)
705         {
707                 for (nodeLevel2 = nodeLevel1->children;
708                         nodeLevel2 != NULL;
709                         nodeLevel2 = nodeLevel2->next)
710                 {
712                         DataFileStatus = 0;
713                         bool HREFFound = FALSE;
714                         bool ETagFound = FALSE;
715                         bool HTTPStatus = FALSE;
717                         for (nodeLevel3 = nodeLevel2->children;
718                         nodeLevel3 != NULL;
719                         nodeLevel3 = nodeLevel3->next)
720                         {
722                                 if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||
723                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||
724                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")
725                                 ){
727                                         // Get the filename.
728                                         
729                                         for (nodeLevel4 = nodeLevel3->children;
730                                         nodeLevel4 != NULL;
731                                         nodeLevel4 = nodeLevel4->next)
732                                         {
733                                         
734                                                 if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||
735                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||
736                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")
737                                                 ){
738                                                 
739                                                         DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);
740                                                         wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));
741                                                 
742                                                         while (wSTDFilename.HasMoreTokens()){
743                                                         
744                                                                 DataFilename = wSTDFilename.GetNextToken();
745                                                         
746                                                         }
747                                                         
748                                                         HREFFound = TRUE;
749                                                 
750                                                 }
751                                                 
752         
753                                         
754                                         }
755                                         
757                                 } else {
759                                         for (nodeLevel4 = nodeLevel3->children;
760                                         nodeLevel4 != NULL;
761                                         nodeLevel4 = nodeLevel4->next)
762                                         {
764                                                 for (nodeStatusLv1 = nodeLevel3->children;
765                                                         nodeStatusLv1 != NULL;
766                                                         nodeStatusLv1 = nodeStatusLv1->next)
767                                                 {
769                                                         if (wxString::FromUTF8((const char*)nodeStatusLv1->content) == wxT("HTTP/1.1 404 Not Found")){
770                 
771                                                                 DataFileStatus = 2;
773                                                                 HTTPStatus = TRUE;
774                                                                                 
775                                                         }
776                                         
777                                                         if ((!xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"status") ||
778                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"d:status") ||
779                                                         !xmlStrcmp(nodeStatusLv1->name, (const xmlChar *)"D:status")) && HTTPStatus == FALSE)
780                                                         {
782                                                                 // Get the filename.
783                                         
784                                                                 for (nodeStatusLv2 = nodeStatusLv1->children;
785                                                                 nodeStatusLv2 != NULL;
786                                                                 nodeStatusLv2 = nodeStatusLv2->next)
787                                                                 {
788                                         
789                                                                         if (!xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"text") ||
790                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"d:text") ||
791                                                                         !xmlStrcmp(nodeStatusLv2->name, (const xmlChar *)"D:text")
792                                                                         ){
794                                                                                 if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 200 OK")){
796                                                                                         DataFileStatus = 1;
797                                                                                         
798                                                                                         HTTPStatus = TRUE;
799                                                                         
800                                                                                 // This is currently in a WebDAV draft and may hopefully be enabled when this changes.
801                                                                         
802                                                                                 //} else if (wxString::FromUTF8((const char*)nodeStatusLv2->content) == wxT("HTTP/1.1 201 Created")){
803                                                                                 
804                                                                                 //      DataFileStatus = 0;
805                                                                                 
806                                                                                 }
807                                                 
808                                                                         }
809                                                 
810         
811                                         
812                                                                 }
813                                                         
814                                                         }
816                                         
817                                                 }
818                                                 
819                                                 for (nodeLevel5 = nodeLevel4->children;
820                                                 nodeLevel5 != NULL;
821                                                 nodeLevel5 = nodeLevel5->next)
822                                                 {
824                                                         if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||
825                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||
826                                                         !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")
827                                                         ){
829                                                                 for (nodeLevel6 = nodeLevel5->children;
830                                                                 nodeLevel6 != NULL;
831                                                                 nodeLevel6 = nodeLevel6->next)
832                                                                 {
834                                                                         // Strip the quotes from the ETag.
835                                                 
836                                                                         ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);
837                                                                         if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){
838                                                 
839                                                                                 ETagData.Remove(0, 1);
840                                                                                 ETagData.RemoveLast();
841                                                 
842                                                                         }
843                                                                 
844                                                                         ETagFound = TRUE;
846                                                                 }
847                                                                 
848                                                         }
850                                                 }       
852                                         }
854                                 }
856                         }
858                         if (HREFFound == TRUE && HTTPStatus == TRUE && DataFileStatus == 2){
859                         
860                                 FileSyncData SData;
861                                         
862                                 SData.ETagData = wxT("");
863                                 SData.DataFlag = DataFileStatus;
864                                         
865                                 ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));                          
866                         
867                         }
869                         if (HREFFound == TRUE && ETagFound == TRUE && HTTPStatus == TRUE){
870                                 
871                                 // Add to the map data.
872                                         
873                                 FileSyncData SData;
874                                         
875                                 SData.ETagData = ETagData;
876                                 SData.DataFlag = DataFileStatus;
877                                         
878                                 ContactListFinal.ListData.insert(std::make_pair(DataFilename, SData));
879                                 
880                         }
881                                 
882                         // Reset the values.
883                                 
884                         HREFFound = FALSE;
885                         ETagFound = FALSE;
886                         HTTPStatus = FALSE;
887                         DataFilename.Clear();
889                         if ((!xmlStrcmp(nodeLevel2->name, (const xmlChar *)"sync-token") ||
890                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"d:sync-token") ||
891                         !xmlStrcmp(nodeLevel2->name, (const xmlChar *)"D:sync-token")) &&
892                         SyncTokenFound == FALSE
893                         ){
895                                 for (nodeLevel3 = nodeLevel2->children;
896                                 nodeLevel3 != NULL;
897                                 nodeLevel3 = nodeLevel3->next)
898                                 {
900                                         if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"text") ||
901                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:text") ||
902                                         !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:text")
903                                         ){
904                         
905                                                 DataSyncToken = wxString::FromUTF8((const char*)nodeLevel3->content);
907                                                 SyncTokenFound = TRUE;
908                         
909                                         }
910                         
911                                 }
912         
913                         }
915                 }
917         }
918         
919         // Get the sync token.
920         
921         if (SyncTokenFound == TRUE){
922         
923                 ContactListFinal.SyncToken = DataSyncToken;
924         
925         } else {
926         
927         }
929         SleepFor(2000000000);
931         /*timespec n1, n2;
932                                                 
933         n1.tv_sec = 0;
934         n1.tv_nsec = 2000000000L;
935                 
936         nanosleep(&n1, &n2);*/
938         xmlFreeDoc(xmlCardDAVDoc);
939         curl_easy_cleanup(conn);
941         SyncDataBuffer.reset();
943         // Get the first result.
945         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