Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Fixed cleaning of old object files
[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 #if defined(__APPLE__)
54         
55         SetConnectionObject(conn);
56         
57 #endif
58         
59         struct CardDAVCURLPasser {
60         
61                 CardDAV *Data;
62                 bool HeaderMode = TRUE;
63         
64         } CardDAVHeader, CardDAVFooter;
66         CardDAVHeader.Data = this;
67         CardDAVHeader.HeaderMode = TRUE;
68         
69         CardDAVFooter.Data = this;
70         CardDAVFooter.HeaderMode = FALSE;
72         wxString Data1;
73         wxString Data2;
74         
75         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + ServerPrefix + ServerFilenameLocation;
76         ServerAddressSSL = wxT("https://") + ServerAddressURL;
77         ServerAddressNormal = wxT("http://") + ServerAddressURL;
78         
79         ServerAuth = ServerUser + wxT(":") + ServerPass;
81         std::map<int,int>::iterator ActIter;
82         struct UploadDataStruc UploadData;
83         
84         
85         ActIter = ActivityListPtr->find((int)ItemIndex);
86         
87         static const char* query =
88         "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
89         "<C:addressbook-query xmlns:D=\"DAV:\""
90         "       xmlns:C=\"urn:ietf:params:xml:ns:carddav\">"
91         "<D:prop><D:getetag/>"
92         "</D:prop>"
93         "<C:filter/>"
94         "</C:addressbook-query>";
96         if (ServerSSL){
98                 wxString ServerCertFilename;
99                 bool MatchingCert = FALSE;
101                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
102                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
103                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
104                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
105                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
106                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
107                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
108                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
109                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
110                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
111                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
112                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
113                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
114                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
115                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
116                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
118 #if defined(__APPLE__) || defined(__WIN32__)
119                 
120 #else
121                 
122                 ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
124                 if (wxFile::Exists(ServerCertFilename) == TRUE){
125                 
126                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
127                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
128                         curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
129                 
130                 }
132 #endif
133                 
134                 claconncode = (curl_easy_perform(conn));
136                 // If CURLE_PEER_FAILED_VERIFICATION is returned, retry without
137                 // the local certificate in use.
139                 if (claconncode == CURLE_PEER_FAILED_VERIFICATION){
140                         
141                         curl_easy_cleanup(conn);
142                         conn = curl_easy_init();
143                         
144                         curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
145                         curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
146                         curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
147                         curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
148                         curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
149                         curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
150                         curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
151                         curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
152                         curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
153                         curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
154                         curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
155                         curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
156                         curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
157                         curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
158                         curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
159                         curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
160                         
161                         claconncode = (curl_easy_perform(conn));
162                         
163                         // If claconncode is CURLE_OK then delete the certificate file as that
164                         // is no longer needed.
165                         
166                         if (claconncode == CURLE_OK){
167                         
168                                 // Delete the certificate file.
169                                 
170                                 wxRemoveFile(ServerCertFilename);
171                         
172                         }
173                 
174                 }
176                 // Check if it fails with a CURLE_SSL_CACERT then compare
177                 // the certificates as PEM files.
178                 
179 #if defined(__APPLE__)
180                 
181 #else
182                 
183                 if (claconncode == CURLE_SSL_CACERT && wxFile::Exists(ServerCertFilename) == TRUE){
185                         CURL *sslerrconn;
186                         sslerrconn = curl_easy_init();
187                         CURLcode sslerrconncode;
189                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
191                         PageData.clear();
192                         PageHeader.clear();
194                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
195                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
196                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
197                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
198                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
199                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
200                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
201                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
202                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
203                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
204                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
205                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
206                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
207                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
208                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 1);
209                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYHOST, 2);
210                         curl_easy_setopt(sslerrconn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
211                 
212                         wxString SSLLocalData;
213                         wxString SSLServerData;
214                 
215                         sslerrconncode = (curl_easy_perform(sslerrconn));
216                 
217                         SSLCertCol = BuildSSLCollection(sslerrconn);
218                         std::map<int, SSLCertData>::iterator SSLCDIter = SSLCertCol.SSLCollection.find(0);
219                         std::multimap<wxString,wxString>::iterator SSLDataIter = SSLCDIter->second.CertData.find(wxT("Cert"));
220                         
221                         wxFFile SSLLocalFile;
222                         
223 #if wxABI_VERSION < 20900
224                         SSLLocalFile.Open(ServerCertFilename.c_str(), wxT("r"));
225 #else
226                         SSLLocalFile.Open(ServerCertFilename, wxT("r"));
227 #endif  
229                         // Load the recovery database for tasks not done.
230         
231                         if (SSLLocalFile.IsOpened() == TRUE){
233                         // Check if we are using wxWidgets version 2.8 or less and
234                         // execute the required command accordingly.
235         
236                                 SSLLocalFile.ReadAll(&SSLLocalData, wxConvAuto());
237                 
238         
239                         }
240                         
241                         SSLServerData = SSLDataIter->second;
242                         
243                         if (SSLLocalData == SSLServerData){
244                         
245                                 // Server key matches with local key so retry with CURLOPT_SSL_VERIFYPEER
246                                 // and CURLOPT_SSL_VERIFYHOST off.
247                         
248                                 curl_easy_cleanup(conn);
249                                 conn = curl_easy_init();
250                                 
251                                 PageData.clear();
252                                 PageHeader.clear();
253                         
254                                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
255                                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
256                                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
257                                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
258                                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
259                                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
260                                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
261                                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
262                                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
263                                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
264                                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
265                                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
266                                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
267                                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
268                                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
269                                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));
270                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0);
271                                 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0);              
272                         
273                                 claconncode = (curl_easy_perform(conn));
274                                 
275                                 MatchingCert = TRUE;
276                         
277                         }
278                         
279                         if (MatchingCert == FALSE){
280                 
281                                 claconncode = CURLE_SSL_CACERT;
282                                 return;
283                 
284                         }
285                         
286                         curl_easy_cleanup(sslerrconn);
287                 
288                 }
289                 
290 #endif
292                 // Sort out SSL error.
293                 
294                 // When SSL cert error occurs, connect again and fetch certificates.
295                 // Display a message to the user explaining that an invalid
296                 // certificate has been given and let the user decide what
297                 // to do next.
299                 if (claconncode == CURLE_OK){
301                 } else if (claconncode == CURLE_SSL_CACERT || claconncode == CURLE_PEER_FAILED_VERIFICATION){
302                 
303                         CURL *sslerrconn;
304                         sslerrconn = curl_easy_init();
305                         CURLcode sslerrconncode;
306                 
307                         wxString ServerAddressOnly = wxT("https://") + ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
308                 
309                         // Replace conn with sslerrconn!
310                 
311                         curl_easy_setopt(sslerrconn, CURLOPT_URL, (const char*)ServerAddressOnly.mb_str(wxConvUTF8));
312                         curl_easy_setopt(sslerrconn, CURLOPT_NOPROGRESS, 0);
313                         curl_easy_setopt(sslerrconn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
314                         curl_easy_setopt(sslerrconn, CURLOPT_TIMEOUT, 60);
315                         curl_easy_setopt(sslerrconn, CURLOPT_FAILONERROR, TRUE);
316                         curl_easy_setopt(sslerrconn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
317                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEFUNCTION, WritebackFunc);
318                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEDATA, &PageData);
319                         curl_easy_setopt(sslerrconn, CURLOPT_WRITEHEADER, &PageHeader);
320                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSDATA, this);
321                         curl_easy_setopt(sslerrconn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
322                         curl_easy_setopt(sslerrconn, CURLOPT_NOSIGNAL, 1);
323                         curl_easy_setopt(sslerrconn, CURLOPT_SSL_VERIFYPEER, 0);
324                         curl_easy_setopt(sslerrconn, CURLOPT_CERTINFO, 1);
325                                         
326                         sslerrconncode = (curl_easy_perform(sslerrconn));
328 #if defined(__APPLE__)
329                         
330                         SetConnectionObject(sslerrconn);
331                         
332 #endif
333                         
334                         SSLCertCol = BuildSSLCollection(sslerrconn);
335                         SSLCertCol.SuccessCode = 1;
337                         curl_easy_cleanup(conn);
338                         curl_easy_cleanup(sslerrconn);
340                         return;
341                 
342                 } else if (claconncode == CURLE_HTTP_RETURNED_ERROR){
343                 
344                         fprintf(stderr, "GetServerETagValueThread(): curl_easy_perform() failed: %s\n",
345                                         curl_easy_strerror(claconncode));
346                         int http_code = 0;
347                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
348                         fprintf(stderr, "Error code was: %d\n", http_code);
350                         curl_easy_cleanup(conn);
351                                         
352                         return;
353                 
354                 } else {
356                         fprintf(stderr, "GetServerETagValueThread(): curl_easy_perform() failed: %s\n",
357                                         curl_easy_strerror(claconncode));
358                         int http_code = 0;
359                         curl_easy_getinfo(conn, CURLINFO_RESPONSE_CODE, &http_code);
360                         fprintf(stderr, "Error code was: %d\n", http_code);
362                         curl_easy_cleanup(conn);
364                         return;
366                 }
368         } else {
369         
370                 // No SSL.
371         
372                 wxString EmptyString;
373                 
374                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
375                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 0);
376                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
377                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
378                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
379                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
380                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
381                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
382                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
383                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
384                 curl_easy_setopt(conn, CURLOPT_PROGRESSDATA, this);
385                 curl_easy_setopt(conn, CURLOPT_PROGRESSFUNCTION, ProgressFunc);
386                 curl_easy_setopt(conn, CURLOPT_CUSTOMREQUEST, "REPORT");
387                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
388                 curl_easy_setopt(conn, CURLOPT_POSTFIELDS, query);
389                 curl_easy_setopt(conn, CURLOPT_POSTFIELDSIZE, strlen(query));           
390                 
391                 PageData.Clear();
392                 PageHeader.Clear();
393                 
394                 conncode = (curl_easy_perform(conn));
396                 if (conncode == CURLE_OK){
398                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
399                 
400                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
401                                         curl_easy_strerror(conncode));
402                                 
403                         return;
404                 
405                 } else {
407                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
408                                         curl_easy_strerror(conncode));
409                                 
410                         return;
412                 }
413                 
414         }
415         
416         xmlDocPtr xmlCardDAVDoc;
418         xmlCardDAVDoc = xmlReadMemory(PageData.mb_str(wxConvUTF8), (int)PageData.Len(), "noname.xml", NULL, 0);
420         xmlNodePtr nodeLevel1;
421         xmlNodePtr nodeLevel2;
422         xmlNodePtr nodeLevel3;
423         xmlNodePtr nodeLevel4;
424         xmlNodePtr nodeLevel5;
425         xmlNodePtr nodeLevel6;
427         std::map<wxString,wxString> xmlDataMap;
429         wxString DataFilename;
430         wxString ETagData;
432         std::string xmlStringSafe;
434         // Tranverse through the catacombs of the response to get our ETag for the file.
436         for (nodeLevel1 = xmlCardDAVDoc->children;
437                 nodeLevel1 != NULL;
438                 nodeLevel1 = nodeLevel1->next)
439         {
441                 bool HREFFound = FALSE;
442                 bool ETagFound = FALSE;
444                 for (nodeLevel2 = nodeLevel1->children;
445                         nodeLevel2 != NULL;
446                         nodeLevel2 = nodeLevel2->next)
447                 {
449                         for (nodeLevel3 = nodeLevel2->children;
450                         nodeLevel3 != NULL;
451                         nodeLevel3 = nodeLevel3->next)
452                         {
454                                 if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||
455                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||
456                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")
457                                 ){
459                                         // Get the filename.
460                                         
461                                         for (nodeLevel4 = nodeLevel3->children;
462                                         nodeLevel4 != NULL;
463                                         nodeLevel4 = nodeLevel4->next)
464                                         {
465                                         
466                                                 if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||
467                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||
468                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")
469                                                 ){
471                                                         DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);
472                                                         wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));
473                                                 
474                                                         while (wSTDFilename.HasMoreTokens()){
475                                                         
476                                                                 DataFilename = wSTDFilename.GetNextToken();
477                                                         
478                                                         }
479                                                         
480                                                         HREFFound = TRUE;
481                                                 
482                                                 }
483                                                 
484         
485                                         
486                                         }
488                                 } else {
490                                         for (nodeLevel4 = nodeLevel3->children;
491                                         nodeLevel4 != NULL;
492                                         nodeLevel4 = nodeLevel4->next)
493                                         {
494                                                         
495                                                         for (nodeLevel5 = nodeLevel4->children;
496                                                         nodeLevel5 != NULL;
497                                                         nodeLevel5 = nodeLevel5->next)
498                                                         {
500                                                                 if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||
501                                                                 !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||
502                                                                 !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")
503                                                                 ){
505                                                                         for (nodeLevel6 = nodeLevel5->children;
506                                                                         nodeLevel6 != NULL;
507                                                                         nodeLevel6 = nodeLevel6->next)
508                                                                         {
509                                                         
510                                                                                 // Strip the quotes from the ETag.
511                                                         
512                                                                                 ETagData = wxString::FromUTF8((const char*)nodeLevel6->content);
513                                                                                 if (ETagData.Mid(0, 1) == wxT("\"") && ETagData.Mid((ETagData.Len() - 1), 1) == wxT("\"")){
514                                                         
515                                                                                         ETagData.Remove(0, 1);
516                                                                                         ETagData.RemoveLast();
517                                                         
518                                                                                 }
519                                                                         
520                                                                                 ETagFound = TRUE;
522                                                                         }
523                                                                         
524                                                                 }
526                                                         }       
528                                         }
530                                 }
532                         }
534                 }
535                 
536                 if (HREFFound == TRUE && ETagFound == TRUE){
537                                 
538                         // Add to the map data.
539                                         
540                         xmlDataMap.insert(std::make_pair(DataFilename, ETagData));
541                                 
542                         HREFFound = FALSE;
543                         ETagFound = FALSE;
544                                 
545                 }
548         }
550         xmlFreeDoc(xmlCardDAVDoc);
552         // Get the first result.
554         for (std::map<wxString,wxString>::iterator iter = xmlDataMap.begin(); 
555                 iter != xmlDataMap.end(); ++iter){
556         
557                 ETagResult = iter->second;
558                 break;
559                 
560         }
561         
562         if (ETagResult.IsEmpty()){
563         
564                 return;
565         
566         }
567         
568         return;
569         
572 void CardDAV::GetServerETagValue(){
574         // Get the server etag value.
575         
576         std::thread ConnectThread(&CardDAV::GetServerETagValueThread, this);
577         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