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