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