Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
efb69c78d96420aa71396f22cd9f1ef74af66c0b
[xestiaab/.git] / source / carddav / carddav-serveretag.cpp
1 // carddav-serveretag.cpp - CardDAV Object - Server ETag 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 void CardDAV::GetServerETagValueThread()
32 {
33         
34         // Get the server etag value (threaded).
36         PageData.Clear();
37         PageHeader.Clear();
39         SSLStatus = TRUE;
40         AuthPassed = TRUE;
41         AbortConnection = FALSE;
42         
43         bool FilenameIsDirectory = FALSE;
44         CURL *conn;
45         CURLcode conncode;
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 + ServerFilenameLocation;
70         ServerAddressSSL = wxT("https://") + ServerAddressURL;
71         ServerAddressNormal = wxT("http://") + ServerAddressURL;
72         
73         ServerAuth = ServerUser + wxT(":") + ServerPass;
74         
75         // Workout if path is directory or filename.
76         
77         /*if (ServerAddress){
78                 FilenameIsDirectory = TRUE;
79         } else {
80                 FilenameIsDirectory = FALSE;
81         }*/
82         
83         // Try SSL first.
86         /*
87         char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];
88         //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());
89         strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));
90         
91         char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];
92         //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());       
93         strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));
95         char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];
96         //memset(ServerAuthChar, 0, ServerAddressSSL.Length()); 
97         strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));
98         
99         */
101         //std::string WriteDataString = std::string(ServerUploadData.mb_str());
103         std::map<int,int>::iterator ActIter;
104         struct UploadDataStruc UploadData;
105         
106         
107         ActIter = ActivityListPtr->find((int)ItemIndex);
108         
109         static const char* query =
110         "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
111         "<C:addressbook-query xmlns:D=\"DAV:\""
112         "       xmlns:C=\"urn:ietf:params:xml:ns:carddav\">"
113         "<D:prop><D:getetag/>"
114         //"<C:address-data>"
115         //"     <C:allprop/>"
116         //"</C:address-data></D:prop>"
117         "</D:prop>"
118         "<C:filter/>"
119         "</C:addressbook-query>";
121         if (ServerSSL){
123                 wxString ServerCertFilename;
124                 bool MatchingCert = FALSE;
126                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
127                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
128                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
129                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
130                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
131                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
132                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
133                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
134                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
135                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
136                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
137                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
138                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
139                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
141                 //UploadData.readptr = &CardDAVDataQuery;
142                 //UploadData.sizeleft = CardDAVDataQuery.Len();
143                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
144                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
145                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
146                 
147                 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);
148                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
149                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
151                 ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
153                 if (wxFile::Exists(ServerCertFilename) == TRUE){
154                 
155                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
156                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
157                         curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
158                 
159                 }
161                 claconncode = (curl_easy_perform(conn));
163                 // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without
164                 // the local certificate in use.
166                 if (claconncode == CURLE_PEER_FAILED_VERIFICATION){
167                         
168                         curl_easy_cleanup(conn);
169                         conn = curl_easy_init();
170                         
171                         curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
172                         curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
173                         curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
174                         curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
175                         curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
176                         curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
177                         curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
178                         curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
179                         curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
180                         curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
181                         curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
182                         curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
183                         curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
184                         curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
185                         curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
186                         curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
187                         
188                         claconncode = (curl_easy_perform(conn));
189                         
190                         // If claconncode is CURLE_OK then delete the certificate file as that
191                         // is no longer needed.
192                         
193                         if (claconncode == CURLE_OK){
194                         
195                                 // Delete the certificate file.
196                                 
197                                 wxRemoveFile(ServerCertFilename);
198                         
199                         }
200                 
201                 }
203                 // Check if it fails with a CURLE_SSL_CACERT then compare
204                 // the certificates as PEM files.
205                 
206                 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
207                 
208                         //curl_easy_cleanup(conn);
209                         //conn = curl_easy_init();
211                         CURL *sslerrconn;
212                         sslerrconn = curl_easy_init();
213                         CURLcode sslerrconncode;
215                         //claconncode = (curl_easy_perform(conn));
217                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
219                         PageData.clear();
220                         PageHeader.clear();
222                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
223                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
224                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
225                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
226                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
227                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
228                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
229                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
230                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
231                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
232                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
233                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
234                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
235                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
236                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 1);
237                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYHOST, 2);
238                         curl_easy_setopt(sslerrconn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
239                 
240                         wxString SSLLocalData;
241                         wxString SSLServerData;
242                 
243                         sslerrconncode = (curl_easy_perform(sslerrconn));
244                 
245                         SSLCertCol = BuildSSLCollection(sslerrconn);
246                         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);
247                         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
248                         
249                         wxFFile SSLLocalFile;
250                         
251 #if wxABI_VERSION < 20900
252                         SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
253 #else
254                         SSLLocalFile.Open(ServerCertFilename, wxT("r"));
255 #endif  
257                         // Load the recovery database for tasks not done.
258         
259                         if (SSLLocalFile.IsOpened() == TRUE){
261                         // Check if we are using wxWidgets version 2.8 or less and
262                         // execute the required command accordingly.
263         
264                                 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
265                 
266         
267                         }
268                         
269                         SSLServerData = SSLDataIter->second;
270                         
271                         if (SSLLocalData == SSLServerData){
272                         
273                                 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
274                                 // and CURLOPT_SSL_VERIFYHOST off.
275                         
276                                 curl_easy_cleanup(conn);
277                                 conn = curl_easy_init();
278                                 
279                                 PageData.clear();
280                                 PageHeader.clear();
281                         
282                                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
283                                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
284                                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
285                                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
286                                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
287                                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
288                                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
289                                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
290                                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
291                                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
292                                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
293                                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
294                                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
295                                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
296                                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
297                                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
298                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);
299                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);              
300                         
301                                 claconncode = (curl_easy_perform(conn));
302                                 
303                                 MatchingCert = TRUE;
304                         
305                         }
306                         
307                         if (MatchingCert == FALSE){
308                 
309                                 claconncode = CURLE_SSL_CACERT;
310                                 return;
311                 
312                         }
313                         
314                         curl_easy_cleanup(sslerrconn);
315                 
316                 }
318                 // Sort out SSL error.
319                 
320                 // When SSL cert error occurs, connect again and fetch certificates.
321                 // Display a message to the user explaining that an invalid
322                 // certificate has been given and let the user decide what
323                 // to do next.
325                 if (claconncode == CURLE_OK){
327                 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
328                 
329                         CURL *sslerrconn;
330                         sslerrconn = curl_easy_init();
331                         CURLcode sslerrconncode;
332                 
333                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
334                 
335                         // Replace conn with sslerrconn!
336                 
337                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
338                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
339                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
340                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
341                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
342                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
343                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
344                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
345                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
346                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
347                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
348                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
349                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
350                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
351                                         
352                         sslerrconncode = (curl_easy_perform(sslerrconn));
354                         SSLCertCol = BuildSSLCollection(sslerrconn);
355                         SSLCertCol.SuccessCode = 1;
357                         curl_easy_cleanup(conn);
358                         curl_easy_cleanup(sslerrconn);
360                         return;
361                 
362                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
363                 
364                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
365                                         curl_easy_strerror(claconncode));
366                         int http_code = 0;
367                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
368                         fprintf(stderr, "Error code was: %d\n", http_code);
370                         curl_easy_cleanup(conn);
371                                         
372                         return;
373                 
374                 } else {
376                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
377                                         curl_easy_strerror(claconncode));
378                         int http_code = 0;
379                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
380                         fprintf(stderr, "Error code was: %d\n", http_code);
382                         curl_easy_cleanup(conn);
384                         return;
386                 }
388         } else {
389         
390                 // No SSL.
391         
392                 wxString EmptyString;
393                 
394                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
395                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
396                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
397                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
398                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
399                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
400                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
401                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
402                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
403                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
404                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
405                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
406                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
407                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
409                 //UploadData.readptr = &CardDAVDataQuery;
410                 //UploadData.sizeleft = CardDAVDataQuery.Len();
411                 //curl_easy_setopt(conn, CURLOPT_UPLOAD, 1);
412                 //curl_easy_setopt(conn, CURLOPT_READDATA, &UploadData);
413                 //curl_easy_setopt(conn, CURLOPT_READFUNCTION, UploadReadFunc);
414                 
415                 //curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writefunc);
416                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
417                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));           
418                 
419                 PageData.Clear();
420                 PageHeader.Clear();
421                 
422                 conncode = (curl_easy_perform(conn));
424                 if (conncode == CURLE_OK){
426                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
427                 
428                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
429                                         curl_easy_strerror(conncode));
430                                 
431                         return;
432                 
433                 } else {
435                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
436                                         curl_easy_strerror(conncode));
437                                 
438                         return;
440                 }
441                 
442         }
443         
444         xmlDocPtr xmlCardDAVDoc;
446         xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);
448         xmlNodePtr nodeLevel1;
449         xmlNodePtr nodeLevel2;
450         xmlNodePtr nodeLevel3;
451         xmlNodePtr nodeLevel4;
452         xmlNodePtr nodeLevel5;
453         xmlNodePtr nodeLevel6;
455         std::map<wxString,wxString> xmlDataMap;
457         wxString DataFilename;
458         wxString ETagData;
460         std::string xmlStringSafe;
462         // Tranverse through the catacombs of the response to get our ETag for the file.
464         for (nodeLevel1 = xmlCardDAVDoc->children;
465                 nodeLevel1 != NULL;
466                 nodeLevel1 = nodeLevel1->next)
467         {
469                 bool HREFFound = FALSE;
470                 bool ETagFound = FALSE;
472                 for (nodeLevel2 = nodeLevel1->children;
473                         nodeLevel2 != NULL;
474                         nodeLevel2 = nodeLevel2->next)
475                 {
477                         for (nodeLevel3 = nodeLevel2->children;
478                         nodeLevel3 != NULL;
479                         nodeLevel3 = nodeLevel3->next)
480                         {
482                                 if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||
483                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||
484                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")
485                                 ){
487                                         // Get the filename.
488                                         
489                                         for (nodeLevel4 = nodeLevel3->children;
490                                         nodeLevel4 != NULL;
491                                         nodeLevel4 = nodeLevel4->next)
492                                         {
493                                         
494                                                 if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||
495                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||
496                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")
497                                                 ){
499                                                         DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);
500                                                         wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));
501                                                 
502                                                         while (wSTDFilename.HasMoreTokens()){
503                                                         
504                                                                 DataFilename = wSTDFilename.GetNextToken();
505                                                         
506                                                         }
507                                                         
508                                                         HREFFound = TRUE;
509                                                 
510                                                 }
511                                                 
512         
513                                         
514                                         }
516                                 } else {
518                                         for (nodeLevel4 = nodeLevel3->children;
519                                         nodeLevel4 != NULL;
520                                         nodeLevel4 = nodeLevel4->next)
521                                         {
522                                                         
523                                                         for (nodeLevel5 = nodeLevel4->children;
524                                                         nodeLevel5 != NULL;
525                                                         nodeLevel5 = nodeLevel5->next)
526                                                         {
528                                                                 if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||
529                                                                 !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||
530                                                                 !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")
531                                                                 ){
533                                                                         for (nodeLevel6 = nodeLevel5->children;
534                                                                         nodeLevel6 != NULL;
535                                                                         nodeLevel6 = nodeLevel6->next)
536                                                                         {
537                                                         
538                                                                                 // Strip the quotes from the ETag.
539                                                         
540                                                                                 ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);
541                                                                                 if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){
542                                                         
543                                                                                         ETagData.Remove(0, 1);
544                                                                                         ETagData.RemoveLast();
545                                                         
546                                                                                 }
547                                                                         
548                                                                                 ETagFound = TRUE;
550                                                                         }
551                                                                         
552                                                                 }
554                                                         }       
556                                         }
558                                 }
560                         }
562                 }
563                 
564                 if (HREFFound == TRUE && ETagFound == TRUE){
565                                 
566                         // Add to the map data.
567                                         
568                         xmlDataMap.insert(std::make_pair(DataFilename, ETagData));
569                                 
570                         HREFFound = FALSE;
571                         ETagFound = FALSE;
572                                 
573                 }
576         }
578         xmlFreeDoc(xmlCardDAVDoc);
580         // Get the first result.
582         for (std::map<wxString,wxString>::iterator iter = xmlDataMap.begin(); 
583                 iter != xmlDataMap.end(); ++iter){
584         
585                 ETagResult = iter->second;
586                 break;
587                 
588         }
589         
590         if (ETagResult.IsEmpty()){
591         
592                 return;
593         
594         }
595         
596         return;
597         
600 void CardDAV::GetServerETagValue(){
602         // Get the server etag value.
603         
604         std::thread ConnectThread(&CardDAV::GetServerETagValueThread, this);
605         ConnectThread.detach();
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