Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
camelCase: Converted code in CalDAV directory
[xestiacalendar/.git] / source / objects / CalDAV / CalDAV.cpp
1 // CalDAV.cpp - CalDAV Connection Object.
2 //
3 // (c) 2016-2017 Xestia Software Development.
4 //
5 // This file is part of Xestia Calendar.
6 //
7 // Xestia Calendar 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 Calendar 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 Calendar. If not, see <http://www.gnu.org/licenses/>
19 #include "CalDAV.h"
21 using namespace std;
23 size_t CalDAVReceive(char *receivedBuffer, size_t size, size_t newMemoryBytes, string *stringPointer)
24 {
25         
26         stringPointer->append(receivedBuffer, newMemoryBytes);
27         
28         return size * newMemoryBytes;
29         
30 }
32 size_t CalDAVSend(char *sendBuffer, size_t size, size_t newMemoryBytes, void *dataStruct){
34         struct CalDAVSendData *uploadPtr = (struct calDAVSendData *)dataStruct;
35         
36         if (uploadPtr->sizeleft){
38                 uploadPtr->sizeleft--;
39                 char charSend;
41                 charSend = (*uploadPtr->readptr)[uploadPtr->seek];
42                 
43                 *sendBuffer = charSend;
44                 
45                 uploadPtr->seek++;
47                 return 1;
49         }
51         return 0;
53 }
55 CalDAV::CalDAV(){
57         // Setup the objects within the CalDAV connection 
58         // object.
59         
60         connectionHandle = curl_easy_init();
61         
62 }
64 CalDAV::~CalDAV(){
65         
66         // Destory the objects within the CalDAV connection
67         // object.
68         
69         curl_easy_cleanup(connectionHandle);
70         connectionHandle = nullptr;
71         
72 }
74 void CalDAV::SetupConnectionData(CalDAVConnectionData *connData){
75         
76         // Check if ConnData is a nullptr, return if it is.
77         
78         if (connData == nullptr){
79                 return;
80         }
81         
82         // Set the connection settings to the values from ConnData.
84         connectionData = (*connData);
85         
86 }
88 CalDAVStatus CalDAV::GetConnectionData(){
89         
90         // Get the current connection settings for the CalDAV
91         // connection object and return a CalDAVStatus object.
92         
93         CalDAVStatus connectionStatus;
94         
95         connectionStatus.hostname = connectionData.hostname;
96         connectionStatus.port = connectionData.port;
97         connectionStatus.username = connectionData.username;
98         connectionStatus.prefix = connectionData.prefix;
99         connectionStatus.useSSL = connectionData.useSSL;
100         connectionStatus.timeout = connectionData.timeout;
101         
102         return connectionStatus;
103         
106 CalDAVServerResult CalDAV::Connect(){
108         CalDAVServerResult serverResult;
110         string serverAddress = "";
111         string serverUserPass = "";
113         // Setup the server address.
114         
115         serverAddress = BuildServerAddress(&connectionData, "/principals/");
117         // Setup the server password.
118         
119         ServerUserPass += connectionData.username;
120         ServerUserPass += ":";
121         ServerUserPass += connectionData.password;
122         
123         curl_easy_setopt(connectionHandle, CURLOPT_URL, serverAddress.c_str());
124         curl_easy_setopt(connectionHandle, CURLOPT_USERPWD, serverUserPass.c_str());
125         curl_easy_setopt(connectionHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
126         curl_easy_setopt(connectionHandle, CURLOPT_FAILONERROR, 1L);
127         curl_easy_setopt(connectionHandle, CURLOPT_TIMEOUT, connectionData.timeout);
128         curl_easy_setopt(connectionHandle, CURLOPT_WRITEFUNCTION, calDAVReceive);
129         curl_easy_setopt(connectionHandle, CURLOPT_WRITEDATA, &serverData);
130         curl_easy_setopt(connectionHandle, CURLOPT_WRITEHEADER, &serverHeader);
131         
132         // Connect to the CalDAV server.
133         
134         serverResult.code = curl_easy_perform(connectionHandle);
136         // Process the result received from the server.
137         
138         if (serverResult.code != CURLE_OK){
139                 
140                 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
141                 
142         } else {
143                 
144                 serverResult.result = CALDAVQUERYRESULT_OK;
145                 
146         }
147         
148         // Get the HTTP code.
149         
150         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
151         
152         return serverResult;
153         
156 CalDAVServerResult CalDAV::GetServerResult(){
157         
158         return connectionServerResult;
159         
162 CalDAVServerSupport CalDAV::GetServerSupport(){
164         CalDAVServerSupport serverStatus;
165         
166         // Setup the server connection.
167         
168         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "OPTIONS");
169         
170         CURLcode serverResult = curl_easy_perform(connectionHandle);
171         
172         // Set the results.
173         
174         if (serverResult == CURLE_OK){
175                 connectionServerResult.result = CALDAVQUERYRESULT_OK;
176         } else {
177                 connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;          
178         }
179         connectionServerResult.code = serverResult;
180         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
181         
182         if (serverResult != CURLE_OK){
183                 return serverStatus;
184         }
185         
186         // Check that the server header has data in,
187         // otherwise return an "empty" CalDAVServerSupport.
188         
189         if (serverHeader.size() == 0){
190                 return serverStatus;
191         }
192         
193         // Process each line looking for the first DAV header 
194         // line.
195         
196         bool newlineMode = true;
197         
198         string davLine;
199         
200         for (int charSeek = 0; charSeek < serverHeader.size(); charSeek++){
201                 
202                 if (newlineMode == true){
203                         
204                         // Check if we have reached the end of the string.
205                         
206                         if (charSeek >= serverHeader.size()){
207                                 
208                                 break;
209                                 
210                         }
211                         
212                         // Check the first four letters to make sure
213                         // they are 'DAV:'.
214                         
215                         string davHeaderCheck = "";
216                         
217                         try {
218                                 davHeaderCheck = serverHeader.substr(charSeek, 4);
219                         }
220                         
221                         catch (out_of_range &oor){
222                                 break;
223                         }
224                         
225                         if (davHeaderCheck == "DAV:"){
226                                 
227                                 charSeek += 5;
228                                 
229                                 for (; charSeek < serverHeader.size(); charSeek++){
230                                         
231                                         if (serverHeader[charSeek] == '\n'){
232                                         
233                                                 break;
234                                                 
235                                         }
236                                         
237                                         davLine.push_back(serverHeader[charSeek]);
238                                         
239                                 }
240                                 
241                                 break;
242                                 
243                         }
244                         
245                         newlineMode = false;
246                         
247                 }
248                 
249                 if (serverHeader[charSeek] == '\n'){
250                         
251                         newlineMode = true;
252                         
253                 }
254                 
255         }
256         
257         // Process the DAV line.
258         
259         vector<string> davLineData;
260         string davSegmentString;
261         
262         for (int charSeek = 0; charSeek < davLine.size(); charSeek++){
263                 
264                 if (davLine[charSeek] == ' '){
265                         continue;
266                 }
267                 
268                 if (davLine[charSeek] == ','){
269                         
270                         davLineData.push_back(davSegmentString);
271                         davSegmentString.clear();
272                         continue;
273                         
274                 }
275                 
276                 davSegmentString += davLine[charSeek];
277                 
278         }
279         
280         // Process the DAV values and set each value
281         // to true as required.
282         
283         for (int davItemSeek = 0; 
284                 davItemSeek < davLineData.size();
285                 davItemSeek++){
286                         
287                 if (davLineData.at(davItemSeek) == "calendar-access"){
288                         
289                         serverStatus.basicSupport = true;
290                 
291                 }
292                         
293         }
294         
295         // Reset the connection status.
296         
297         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
298         
299         return serverStatus;
300         
303 string CalDAV::GetUserPrincipal(){
304         
305         string currentUserPrincipal = "";
306         string userPrincipalRequest = "";
307         CalDAVSendData userPrincipalSendData;
308         
309         userPrincipalRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
310         "<d:propfind xmlns:d=\"DAV:\">\n"
311         " <d:prop>\n"
312         "  <d:current-user-principal />\n"
313         " </d:prop>\n"
314         "</d:propfind>";
315         
316         userPrincipalSendData.readptr = &userPrincipalRequest;
317         userPrincipalSendData.sizeleft = userPrincipalRequest.size();
318         
319         // Setup the header.
320         
321         struct curl_slist *userPrincipalRequestHeader = NULL;
322         
323         userPrincipalRequestHeader = curl_slist_append(userPrincipalRequestHeader, "Depth: 0");
324         userPrincipalRequestHeader = curl_slist_append(userPrincipalRequestHeader, "Prefer: return-minimal");
325         userPrincipalRequestHeader = curl_slist_append(userPrincipalRequestHeader, "Content-Type: application/xml; charset=utf-8");
326         
327         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, userPrincipalRequestHeader);
329         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
330         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
331         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &userPrincipalSendData);
332         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, calDAVSend);
333         
334         // Process the data.
335         
336         serverData.clear();
337         serverHeader.clear();
338         
339         CURLcode serverResult = curl_easy_perform(connectionHandle);
340         
341         // Set the results.
342         
343         if (serverResult == CURLE_OK){
344                 connectionServerResult.Result = CALDAVQUERYRESULT_OK;
345         } else {
346                 connectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;          
347         }
348         connectionServerResult.Code = serverResult;
349         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.HTTPCode);
350         
351         if (serverResult != CURLE_OK){
352                 
353                 return currentUserPrincipal;
354                 
355         }
356         
357         // Process the User Principal from the ServerData.
359         currentUserPrincipal = ProcessXMLUserPrincipal();
360         
361         // Reset the changed settings.
362         
363         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
364         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
365         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
367         return currentUserPrincipal;
371 string CalDAV::GetCalendarHome(string userPrincipalURI){
372         
373         string calendarHomeURI = "";
375         // Build the Calendar Home URL address.
376         
377         string calendarHomeURL = BuildServerAddress(&connectionData, userPrincipalURI);
378         
379         // Setup the header request.
380         
381         CalDAVSendData calendarHomeSendData;
382         
383         string calendarHomeRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
384         "<d:propfind xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
385         " <d:prop>\n"
386         "  <c:calendar-home-set />\n"
387         " </d:prop>\n"
388         "</d:propfind>";
389         
390         calendarHomeSendData.readptr = &calendarHomeRequest;
391         calendarHomeSendData.sizeleft = calendarHomeRequest.size();
392         
393         // Setup the header.
394         
395         struct curl_slist *calendarRequestHeader = NULL;
396         
397         calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Depth: 0");
398         calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Prefer: return-minimal");
399         calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Content-Type: application/xml; charset=utf-8");
400         
401         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarRequestHeader);
402         curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarHomeURL.c_str());
403         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
404         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
405         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarHomeSendData);
406         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, calDAVSend);
407         
408         // Process the data.
409         
410         serverData.clear();
411         serverHeader.clear();
412         
413         CURLcode serverResult = curl_easy_perform(connectionHandle);
414         
415         // Set the results.
416         
417         if (serverResult == CURLE_OK){
418                 connectionServerResult.result = CALDAVQUERYRESULT_OK;
419         } else {
420                 connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;          
421         }
422         connectionServerResult.code = serverResult;
423         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
424         
425         if (serverResult != CURLE_OK){
426                 
427                 return calendarHomeURI;
428                 
429         }
430         
431         // Process the User Principal from the ServerData.
433         calendarHomeURI = ProcessXMLCalendarHome();
434         
435         // Reset the changed settings.
436         
437         string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
438         curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
439         
440         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
441         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
442         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
443         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
444         
445         return calendarHomeURI;
446         
449 CalDAVCalendarList CalDAV::GetCalendars(){
450         
451         CalDAVCalendarList serverList;
452         CalDAVSendData calendarListSendData;
453         
454         // Build the server address.
455         
456         string userPrincipalURI = "";
457         userPrincipalURI = GetUserPrincipal();
458         
459         if (userPrincipalURI.size() == 0){
460                 
461                 return serverList;
462                 
463         }
464         
465         string calendarHomeURI = "";
466         calendarHomeURI = GetCalendarHome(userPrincipalURI);
467         
468         string calendarListURLAddress = BuildServerAddress(&connectionData, calendarHomeURI);
469         
470         string calendarListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
471         "<d:propfind xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
472         " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
473         " <d:prop>\n"
474         "  <d:resourcetype />\n"
475         "  <d:displayname />\n"
476         "  <d:sync-token />\n"
477         "  <x0:calendar-color />\n"
478         "  <x0:calendar-order />\n"
479         "  <cs:getctag />\n"
480         "  <c:supported-calendar-component-set />\n"
481         "  <c:calendar-description />\n"
482         " </d:prop>\n"
483         "</d:propfind>";
484         
485         calendarListSendData.readptr = &calendarListRequest;
486         calendarListSendData.sizeleft = calendarListRequest.size();
487         
488         // Setup the header.
489         
490         struct curl_slist *calendarListRequestHeader = NULL;
491         
492         calendarListRequestHeader = curl_slist_append(calendarListRequestHeader, "Depth: 1");
493         calendarListRequestHeader = curl_slist_append(calendarListRequestHeader, "Prefer: return-minimal");
494         calendarListRequestHeader = curl_slist_append(calendarListRequestHeader, "Content-Type: application/xml; charset=utf-8");
495         
496         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarListRequestHeader);
497         curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarListURLAddress.c_str());
498         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
499         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
500         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarListSendData);
501         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, calDAVSend);
502         
503         // Process the data.
504         
505         serverData.clear();
506         serverHeader.clear();
507         
508         CURLcode serverResult = curl_easy_perform(connectionHandle);
509         
510         //ServerList = ProcessXMLCalendarList();
511         
512         if (serverResult == CURLE_OK){
513                 connectionServerResult.result = CALDAVQUERYRESULT_OK;
514         } else {
515                 connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;          
516         }
517         connectionServerResult.code = serverResult;
518         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
519         
520         if (cerverResult != CURLE_OK){
521                 
522                 return serverList;
523                 
524         }
525         
526         // Process the received XML data into a list of calendars
527         // and locations.
528         
529         serverList = ProcessXMLCalendarList();
530         
531         // Restore the original settings.
532         
533         string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
534         
535         curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
536         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
537         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
538         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
539         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
540         
541         return serverList;
542         
545 CalDAVEntryList CalDAV::GetEntryList(string *calendarHREF){
546         
547         CalDAVEntryList entryList;
548         CalDAVSendData entryListSendData;
549         
550         if (calendarHREF->size() == 0){
551                 
552                 return entryList;
553                 
554         }
555         
556         string entryListURLAddress = BuildServerAddress(&connectionData, *calendarHREF);
557         
558         string entryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
559         
560         /*if (CalendarTag == nullptr){*/
561                 
562         entryListRequest += "<c:calendar-query xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
563         " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
564         " <d:prop>\n"
565         "  <d:getetag />\n"
566         "  <c:calendar-data />\n"
567         " </d:prop>\n"
568         " <c:filter>\n"
569         "  <c:comp-filter name=\"VCALENDAR\" />\n"
570         " </c:filter>\n"
571         "</c:calendar-query>";
572                 
573         /*} else {
575                 EntryListRequest += "<d:sync-collection xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
576                 " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"          
577                 " <d:sync-token>";
578                 EntryListRequest += *CalendarTag;
579                 EntryListRequest += "</d:sync-token>\n"
580                 " <d:sync-level>1</d:sync-level>\n"
581                 " <d:prop>\n"
582                 "  <d:getetag />\n"
583                 "  <c:calendar-data />\n"
584                 " </d:prop>\n"
585                 "</d:sync-collection>";
586                 
587         }*/
588         
589         entryListSendData.readptr = &entryListRequest;
590         entryListSendData.sizeleft = entryListRequest.size();
591         
592         struct curl_slist *entryListRequestHeader = NULL;
593         
594         entryListRequestHeader = curl_slist_append(entryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
595         
596         /*if (CalendarTag != nullptr){
597         
598                 EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
599                 EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
600                 
601         }*/
602         
603         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, entryListRequestHeader);
604         curl_easy_setopt(connectionHandle, CURLOPT_URL, entryListURLAddress.c_str());
605         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
606         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
607         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryListSendData);
608         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, calDAVSend);
609         
610         // Process the data.
611         
612         serverData.clear();
613         serverHeader.clear();
614         
615         CURLcode serverResult = curl_easy_perform(connectionHandle);
616         
617         //ServerList = ProcessXMLCalendarList();
618         
619         if (serverResult == CURLE_OK){
620                 connectionServerResult.result = CALDAVQUERYRESULT_OK;
621         } else {
622                 connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;          
623         }
624         connectionServerResult.code = serverResult;
625         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
626         
627         if (serverResult != CURLE_OK){
628                 
629                 return entryList;
630                 
631         }
632         
633         // Process the received XML data into a list of calendars
634         // and locations.
635         
636         entryList = ProcessXMLEntryList();
637         
638         // Restore the original settings.
639         
640         string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
641         
642         curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
643         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
644         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
645         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
646         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
647         
648         return entryList;
649         
652 CalDAVEntryList CalDAV::GetEntryList(string *calendarHREF, string *calendarTag){
653         
654         CalDAVEntryList entryList;
655         CalDAVSendData entryListSendData;
656         
657         if (calendarHREF->size() == 0){
658                 
659                 return entryList;
660                 
661         }
662         
663         string entryListURLAddress = BuildServerAddress(&connectionData, *calendarHREF);
664         
665         // First query: Get the list of contacts that need to be updated.
666         
667         string entryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
669         entryListRequest += "<d:sync-collection xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
670         " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
671         " <d:sync-token>";
672         
673         if (calendarTag != nullptr){
674         
675                 entryListRequest += *calendarTag;
676                 
677         } else {
678         
679                 entryListRequest += "";
680                 
681         }
683         entryListRequest += "</d:sync-token>\n"
684         " <d:sync-level>1</d:sync-level>\n"
685         " <d:prop>\n"
686         "  <d:getetag />\n"
687         " </d:prop>\n"
688         "</d:sync-collection>";
689         
690         entryListSendData.readptr = &entryListRequest;
691         entryListSendData.sizeleft = entryListRequest.size();
692         
693         struct curl_slist *entryListRequestHeader = NULL;
694         
695         entryListRequestHeader = curl_slist_append(entryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
696         
697         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, entryListRequestHeader);
698         curl_easy_setopt(connectionHandle, CURLOPT_URL, entryListURLAddress.c_str());
699         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
700         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
701         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryListSendData);
702         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, calDAVSend);
703         
704         // Process the data.
705         
706         serverData.clear();
707         serverHeader.clear();
708         
709         CURLcode serverResult = curl_easy_perform(connectionHandle);
710         
711         if (serverResult == CURLE_OK){
712                 connectionServerResult.result = CALDAVQUERYRESULT_OK;
713         } else {
714                 connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;          
715         }
716         connectionServerResult.code = serverResult;
717         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
718         
719         if (serverResult != CURLE_OK){
720                 
721                 return entryList;
722                 
723         }
724         
725         entryList = ProcessXMLSyncTokenList();
726         
727         // Check the last entry matches the HREF and if it 
728         // does then delete it.
729         
730         if (entryList.href.size() > 0) {
731         
732                 if (entryList.href.rbegin()->second == *calendarHREF){
733                         
734                         entryList.href.erase((entryList.href.size() - 1));
735                         entryList.tag.erase((entryList.href.size() - 1));
736                         entryList.data.erase((entryList.href.size() - 1));
737                 
738                 }
739         
740         }
741         
742         // Build the list into a new list for getting the new 
743         // calendar data with.
744         
745         entryListRequest.clear();
746         
747         entryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
749         entryListRequest += "<c:calendar-multiget xmlns:d=\"DAV:\" "
750         " xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
751         " <d:prop>\n"
752         "  <d:getetag />\n"
753         "  <c:calendar-data />\n"
754         " </d:prop>\n";
755         
756         for (std::map<int,string>::iterator hrefIter = entryList.href.begin(); 
757                 hrefIter != entryList.href.end(); hrefIter++){
758                 
759                 string entryListHREFString = hrefIter->second;
760                         
761                 entryListRequest += " <d:href>";
762                 entryListRequest += entryListHREFString;
763                 entryListRequest += "</d:href>\n";
764                         
765         }
766         
767         entryListRequest += "</c:calendar-multiget>";
768         
769         CalDAVSendData updatedEntryListSendData;        
770         
771         updatedEntryListSendData.readptr = &entryListRequest;
772         updatedEntryListSendData.sizeleft = entryListRequest.size();
773         
774         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, entryListRequestHeader);
775         curl_easy_setopt(connectionHandle, CURLOPT_URL, entryListURLAddress.c_str());
776         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
777         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
778         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &updatedEntryListSendData);
779         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, calDAVSend);
780         
781         // Get the updated calendar data.
782         
783         serverData.clear();
784         serverHeader.clear();
785         entryList.href.clear();
786         entryList.tag.clear();
787         entryList.data.clear();
788         
789         serverResult = curl_easy_perform(connectionHandle);
791         // Check the last entry matches the HREF and if it 
792         // does then delete it.
793         
794         if (serverResult == CURLE_OK){
795                 connectionServerResult.result = CALDAVQUERYRESULT_OK;
796         } else {
797                 connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;          
798         }
799         connectionServerResult.code = serverResult;
800         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
801         
802         if (serverResult != CURLE_OK){
803                 
804                 return entryList;
805                 
806         }
807         
808         entryList = ProcessXMLEntryList();
809         
810         // Second query: Get the list of contact data for the contacts that have
811         // beenchanged.
812         
813         // Restore the original settings.
814         
815         string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
816         
817         curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
818         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
819         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
820         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
821         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
822         
823         return entryList;
824         
827 CalDAVServerResult CalDAV::AddCalendar(string calendarName){
828         
829         CalDAVServerResult serverResult;
830         
831         AddCalendar(&calendarName, nullptr);
832         
833         return serverResult;
834         
837 CalDAVServerResult CalDAV::AddCalendar(string *calendarName, string *calendarShortName){
838         
839         CalDAVServerResult serverResult;
840         CalDAVSendData calendarAddSendData;
841         
842         // Build the server address.
843         
844         string userPrincipalURI = "";
845         userPrincipalURI = GetUserPrincipal();
846         
847         if (userPrincipalURI.size() == 0){
848                 
849                 return ServerResult;
850                 
851         }
852         
853         string calendarHomeURI = "";
854         calendarHomeURI = GetCalendarHome(userPrincipalURI);
855         
856         // Generate the UUID.
857         
858         string UUIDValue = "";
859         
860         if (calendarShortName == nullptr){
861         
862                 UUIDValue = GenerateUUID();
863                 UUIDValue.erase(UUIDValue.end()-1);
865         } else {
866         
867                 UUIDValue = *calendarShortName;
868                 
869         }
870                 
871         string calendarHomeURL = calendarHomeURI;
872         calendarHomeURL.append(UUIDValue);
873         calendarHomeURL.append("/");
874         
875         // Build the calendar list address.
876         
877         string calendarListURLAddress = BuildServerAddress(&connectionData, calendarHomeURL);
878         
879         string calendarAddRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
880         "<c:mkcalendar xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
881         " <d:set>\n"
882         "  <d:prop>\n"
883         "   <d:displayname>";
884         calendarAddRequest += *calendarName;
885         calendarAddRequest += "</d:displayname>\n"
886         "   <c:supported-calendar-component-set>\n"
887         "    <c:comp name=\"VTODO\"/>\n"
888         "    <c:comp name=\"VEVENT\"/>\n"
889         "   </c:supported-calendar-component-set>\n"
890         "  </d:prop>\n"
891         " </d:set>\n"
892         "</c:mkcalendar>";
893         
894         calendarAddSendData.readptr = &calendarAddRequest;
895         calendarAddSendData.sizeleft = calendarAddRequest.size();
896         
897         // Setup the header.
898         
899         struct curl_slist *calendarRequestHeader = NULL;
900         
901         //curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
902         curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarListURLAddress.c_str());
903         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "MKCALENDAR");
904         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
905         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarAddSendData);
906         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, calDAVSend);
907         
908         // Process the data.
909         
910         serverData.clear();
911         serverHeader.clear();
912         
913         CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
914         
915         if (serverConnectionResult == CURLE_OK){
916                 serverResult.result = CALDAVQUERYRESULT_OK;
917         } else {
918                 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;            
919         }
920         serverResult.code = serverConnectionResult;
921         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
922         
923         // Restore the original settings.
924         
925         string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
926         curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
927         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
928         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
929         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
930         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
931         
932         return serverResult;
933         
936 CalDAVServerResult CalDAV::EditCalendarProcess(string *calendarHREF,
937                         string *calendarName,
938                         Colour *calendarColour,
939                         string *calendarDescription,
940                         int *calendarOrder){
942         CalDAVServerResult serverResult;
943         CalDAVSendData calendarEditSendData;
944         
945         // Build the server address.
946         
947         string userPrincipalURI = "";
948         userPrincipalURI = GetUserPrincipal();
949         
950         if (userPrincipalURI.size() == 0){
951                 
952                 return serverResult;
953                 
954         }
955         
956         string calendarHomeURI = "";
957         calendarHomeURI = GetCalendarHome(userPrincipalURI);
958         
959         // Generate the UUID.
960         
961         string UUIDValue = GenerateUUID();
962         UUIDValue.erase(UUIDValue.end()-1);
963         
964         string calendarHomeURL = calendarHomeURI;
965         calendarHomeURL.append(UUIDValue);
966         calendarHomeURL.append("/");
967         
968         // Build the calendar list address.
969         
970         string calendarEditURLAddress = BuildServerAddress(&connectionData, (*calendarHREF));
971         
972         string calendarEditRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
973         "<d:propertyupdate xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\"\n"
974         "       xmlns:x0=\"http://apple.com/ns/ical/\">\n"
975         " <d:set>\n"
976         "  <d:prop>\n";
977         
978         // Update the calendar name.
979         
980         if (calendarName != nullptr){
981         
982                 calendarEditRequest += "<d:displayname>";
983                 calendarEditRequest += (*calendarName);
984                 calendarEditRequest += "</d:displayname>\n";
985                 
986         }
987         
988         // Update the calendar colour.
989         
990         if (calendarColour != nullptr){
991                 
992                 calendarEditRequest += "<x0:calendar-color>";
993                 calendarEditRequest += (*calendarColour);
994                 calendarEditRequest += "</x0:calendar-color>\n";
995                 
996         }
997         
998         // Update the calendar description.
999         
1000         if (calendarDescription != nullptr){
1001                 
1002                 calendarEditRequest += "<c:calendar-description>";
1003                 calendarEditRequest += (*calendarDescription);
1004                 calendarEditRequest += "</c:calendar-description>\n";           
1005                 
1006         }
1007         
1008         // Update the calendar order.
1009         
1010         if (calendarOrder != nullptr){
1011                 
1012                 calendarEditRequest += "<x0:calendar-order>";
1013                 calendarEditRequest += to_string((*calendarOrder));
1014                 calendarEditRequest += "</x0:calendar-order>\n";
1015                 
1016         }
1017         
1018         calendarEditRequest += "  </d:prop>\n"
1019         " </d:set>\n"
1020         "</d:propertyupdate>";
1021         
1022         calendarEditSendData.readptr = &calendarEditRequest;
1023         calendarEditSendData.sizeleft = calendarEditRequest.size();
1024         
1025         // Setup the header.
1026         
1027         struct curl_slist *calendarRequestHeader = NULL;
1028         
1029         //curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
1030         curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarEditURLAddress.c_str());
1031         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPPATCH");
1032         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
1033         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarEditSendData);
1034         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, calDAVSend);
1035         
1036         // Process the data.
1037         
1038         serverData.clear();
1039         serverHeader.clear();
1040         
1041         CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
1042         
1043         if (serverConnectionRsult == CURLE_OK){
1044                 serverResult.result = CALDAVQUERYRESULT_OK;
1045         } else {
1046                 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;            
1047         }
1048         serverResult.code = serverConnectionResult;
1049         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
1050         
1051         // Restore the original settings.
1052         
1053         string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
1054         curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
1055         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
1056         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
1057         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
1058         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
1059         
1060         return ServerResult;
1064 CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
1065                         string *calendarName,
1066                         Colour *calendarColour,
1067                         string *calendarDescription,
1068                         int *calendarOrder){
1069         
1070         CalDAVServerResult serverResult;
1071         
1072         serverResult = EditCalendarProcess(calendarHREF,
1073                 calendarName,
1074                 calendarColour,
1075                 calendarDescription,
1076                 calendarOrder);
1077                                 
1078         return serverResult;
1079         
1082 CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF,
1083                         Colour *CalendarColour){
1084         
1086         CalDAVServerResult serverResult;
1088         serverResult = EditCalendarProcess(calendarHREF,
1089                 nullptr,
1090                 calendarColour,
1091                 nullptr,
1092                 nullptr);
1093                                 
1094         return serverResult;    
1095         
1098 CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
1099                         string *calendarName){
1100         
1101         CalDAVServerResult serverResult;
1102         
1103         serverResult = EditCalendarProcess(calendarHREF,
1104                 calendarName,
1105                 nullptr,
1106                 nullptr,
1107                 nullptr);       
1108         
1109         return serverResult;
1110         
1113 CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
1114                         int *calendarOrder){
1115         
1116         CalDAVServerResult serverResult;
1117         
1118         serverResult = EditCalendarProcess(calendarHREF,
1119                 nullptr,
1120                 nullptr,
1121                 nullptr,
1122                 calendarOrder);
1123         
1124         return serverResult;
1125         
1128 CalDAVServerResult CalDAV::EditCalendarDescription(string *calendarHREF,
1129                         string *calendarDescription){
1130         
1131         CalDAVServerResult serverResult;
1132         
1133         serverResult = EditCalendarProcess(calendarHREF,
1134                 nullptr,
1135                 nullptr,
1136                 calendarDescription,
1137                 nullptr);
1138         
1139         return serverResult;
1140         
1143 CalDAVServerResult CalDAV::DeleteCalendar(string *calendarHREF){
1145         CalDAVServerResult serverResult;
1146         
1147         // Build the server address.
1148         
1149         string userPrincipalURI = "";
1150         userPrincipalURI = GetUserPrincipal();
1151         
1152         if (userPrincipalURI.size() == 0){
1153                 
1154                 return serverResult;
1155                 
1156         }
1157         
1158         string calendarHomeURI = "";
1159         calendarHomeURI = GetCalendarHome(userPrincipalURI);
1160         
1161         // Generate the UUID.
1162         
1163         string UUIDValue = GenerateUUID();
1164         UUIDValue.erase(UUIDValue.end()-1);
1165         
1166         string calendarHomeURL = calendarHomeURI;
1167         calendarHomeURL.append(UUIDValue);
1168         calendarHomeURL.append("/");
1169         
1170         // Build the calendar list address.
1171         
1172         struct curl_slist *deleteRequestHeader = NULL;
1173         
1174         deleteRequestHeader = curl_slist_append(deleteRequestHeader, "Depth: infinity");
1175         
1176         string calendarDeleteURLAddress = BuildServerAddress(&connectionData, (*calendarHREF));
1177         
1178         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, deleteRequestHeader);
1179         curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarDeleteURLAddress.c_str());
1180         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
1181         
1182         // Delete the calendar.
1183         
1184         serverData.clear();
1185         serverHeader.clear();
1186         
1187         CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
1188         
1189         if (serverConnectionResult == CURLE_OK){
1190                 serverResult.Result = CALDAVQUERYRESULT_OK;
1191         } else {
1192                 serverResult.Result = CALDAVQUERYRESULT_SERVERERROR;            
1193         }
1194         serverResult.code = serverConnectionResult;
1195         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
1196         
1197         // Restore the original settings.
1198         
1199         string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
1200         curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
1201         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
1202         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
1203         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
1204         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
1205         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
1206         
1207         return serverResult;
1208         
1211 CalDAVServerResult CalDAV::GetEntryETag(string *calendarEntryHREF, string *eTagValue){
1212         
1213         CalDAVServerResult serverResult;
1214         CalDAVSendData entryETagGetData;
1215         
1216         // Build the server address.
1217         
1218         string userPrincipalURI = "";
1219         userPrincipalURI = GetUserPrincipal();
1220         
1221         if (userPrincipalURI.size() == 0){
1222                 
1223                 return serverResult;
1224                 
1225         }
1226         
1227         string calendarHomeURI = "";
1228         calendarHomeURI = GetCalendarHome(userPrincipalURI);
1230         // Split the path and filename.
1231         
1232         string entryURIPath;
1233         string entryFilename;
1234         
1235         SplitPathFilename(calendarEntryHREF, &entryURIPath, &entryFilename);
1236         
1237         // Build the request for the server.
1239         string entryETagRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1240         "<c:calendar-multiget xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
1241         " <d:prop>\n"
1242         "  <d:getetag />\n"
1243         " </d:prop>\n"
1244         " <d:href>";
1245         entryETagRequest += (*calendarEntryHREF);
1246         entryETagRequest += "</d:href>\n"
1247         "</c:calendar-multiget>";
1248         
1249         entryETagGetData.readptr = &entryETagRequest;
1250         entryETagGetData.sizeleft = entryETagRequest.size();
1251         
1252         // Build the calendar list address.
1253         
1254         struct curl_slist *getETagRequestHeader = NULL;
1256         getETagRequestHeader = curl_slist_append(getETagRequestHeader, "Depth: 1");     
1257         getETagRequestHeader = curl_slist_append(getETagRequestHeader, "Prefer: return-minimal");
1258         getETagRequestHeader = curl_slist_append(getETagRequestHeader, "Content-Type: application/xml; charset=utf-8");
1259         
1260         string getETagURLAddress = BuildServerAddress(&connectionData, entryURIPath);
1261         
1262         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, getETagRequestHeader);
1263         curl_easy_setopt(connectionHandle, CURLOPT_URL, getETagURLAddress.c_str());
1264         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
1265         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
1266         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryETagGetData);
1267         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, calDAVSend);
1268         
1269         // Attempt to get the entity tag.
1270         
1271         serverData.clear();
1272         serverHeader.clear();
1273         
1274         CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
1275         
1276         if (serverConnectionResult == CURLE_OK){
1277                 serverResult.result = CALDAVQUERYRESULT_OK;
1278         } else {
1279                 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;            
1280         }
1281         serverResult.code = serverConnectionResult;
1282         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
1283         
1284         if (serverConnectionResult != CURLE_OK){
1285                 return serverResult;
1286         }
1287         
1288         // Get the entity tag from the result.
1289         
1290         *eTagValue = ProcessXMLEntryETag();
1291         
1292         // Restore the original settings.
1293         
1294         string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
1295         curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
1296         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
1297         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
1298         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
1299         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
1300         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
1301         
1302         return serverResult;
1303         
1306 CalDAVServerResult CalDAV::AddEntry(string *calendarEntryHREF, string *entryData){
1307         
1308         // Add an entry to the calendar collection.
1309         
1310         CalDAVServerResult serverResult;
1311         CalDAVSendData entryAddSendData;
1312         
1313         // Build the calendar list address.
1314         
1315         string entryAddURLAddress = BuildServerAddress(&connectionData, (*calendarEntryHREF));
1316         
1317         entryAddSendData.readptr = entryData;
1318         entryAddSendData.sizeleft = entryData->size();
1319         
1320         struct curl_slist *calendarRequestHeader = NULL;
1321         
1322         calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Content-Type: text/calendar; charset=utf-8");
1323         
1324         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarRequestHeader);
1325         curl_easy_setopt(connectionHandle, CURLOPT_URL, entryAddURLAddress.c_str());
1326         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PUT");
1327         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
1328         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryAddSendData);
1329         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, calDAVSend);
1330         
1331         // Process the data.
1332         
1333         serverData.clear();
1334         serverHeader.clear();
1335         
1336         CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
1337         
1338         if (serverConnectionResult == CURLE_OK){
1339                 serverResult.result = CALDAVQUERYRESULT_OK;
1340         } else {
1341                 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;            
1342         }
1343         serverResult.code = serverConnectionResult;
1344         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
1345         
1346         // Restore the original settings.
1347         
1348         string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
1349         curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
1350         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
1351         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
1352         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
1353         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
1354         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
1355         
1356         return serverResult;
1357         
1360 CalDAVServerResult CalDAV::EditEntry(string *calendarEntryHREF, string *entryData, string *entryETag){
1361         
1362         // Edit an entry in the calendar collection.
1364         // Add an entry to the calendar collection.
1365         
1366         CalDAVServerResult serverResult;
1367         CalDAVSendData entryAddSendData;
1368         
1369         // Build the calendar list address.
1370         
1371         string entryAddURLAddress = BuildServerAddress(&connectionData, (*calendarEntryHREF));
1372         
1373         entryAddSendData.readptr = entryData;
1374         entryAddSendData.sizeleft = entryData->size();
1375         
1376         string ifMatchHeader = "If-Match: \"";
1377         ifMatchHeader.append(*entryETag);
1378         ifMatchHeader.append("\"");
1379         
1380         struct curl_slist *calendarRequestHeader = NULL;
1381         
1382         calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Content-Type: text/calendar; charset=utf-8");
1383         calendarRequestHeader = curl_slist_append(calendarRequestHeader, ifMatchHeader.c_str());        
1384         
1385         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarRequestHeader);
1386         curl_easy_setopt(connectionHandle, CURLOPT_URL, entryAddURLAddress.c_str());
1387         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PUT");
1388         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
1389         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryAddSendData);
1390         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, calDAVSend);
1391         
1392         // Process the data.
1393         
1394         serverData.clear();
1395         serverHeader.clear();
1396         
1397         CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
1398         
1399         if (serverConnectionResult == CURLE_OK){
1400                 serverResult.result = CALDAVQUERYRESULT_OK;
1401         } else {
1402                 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;            
1403         }
1404         serverResult.code = serverConnectionResult;
1405         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
1406         
1407         // Restore the original settings.
1408         
1409         string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
1410         curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
1411         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
1412         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
1413         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
1414         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
1415         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
1416         
1417         return serverResult;
1418         
1421 CalDAVServerResult CalDAV::DeleteEntry(string *calendarEntryHREF){
1422         
1423         // Delete an entry in the calendar collection.
1424         
1425         CalDAVServerResult serverResult;
1426         
1427         // Build the calendar list address.
1428         
1429         string entryDeleteURLAddress = BuildServerAddress(&connectionData, (*calendarEntryHREF));
1430         
1431         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
1432         curl_easy_setopt(connectionHandle, CURLOPT_URL, entryDeleteURLAddress.c_str());
1433         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
1434         
1435         // Delete the calendar.
1436         
1437         serverData.clear();
1438         serverHeader.clear();
1439         
1440         CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
1441         
1442         if (serverConnectionResult == CURLE_OK){
1443                 serverResult.result = CALDAVQUERYRESULT_OK;
1444         } else {
1445                 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;            
1446         }
1447         serverResult.code = serverConnectionResult;
1448         curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
1449         
1450         // Restore the original settings.
1451         
1452         string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
1453         curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
1454         curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);        
1455         curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
1456         curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
1457         curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
1458         curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
1459         
1460         return serverResult;
1461         
1464 bool CalDAVObjectValidSettings(CalDAVConnectionData *connData){
1466         // Check if the passed CalDAV Connection Data is has
1467         // an address set. Return false if nullptr is used.
1469         if (connData == nullptr){
1470         
1471                 return false;
1472         
1473         }
1474         
1475         // Check the server hostname. Return false
1476         // if no value has been set.
1477         
1478         if (connData->hostname.size() == 0){
1479         
1480                 return false;
1481         
1482         }
1483         
1484         // Check the server port. Return false if
1485         // no value has been set or the port number
1486         // is less than 1 or higher than 65535.
1487         
1488         if (connData->port < 1 || connData->port > 65535){
1489         
1490                 return false;
1491         
1492         }
1493         
1494         // Check the server username. Return false
1495         // if no value has been set.
1496         
1497         if (connData->username.size() == 0){
1498                 
1499                 return false;
1500                 
1501         }       
1502         
1503         // Check the server password. Return false
1504         // if no value has been set.
1505         
1506         if (connData->password.size() == 0){
1507                 
1508                 return false;
1509                 
1510         }
1512         // Cannot check UseSSL: It is either true
1513         // or false.
1514         
1515         // Cannot check Prefix: The prefix may need
1516         // to be worked out first.
1518         // No errors were found whilst checking so
1519         // return true.
1520         
1521         return true;
1525 string BuildServerAddress(CalDAVConnectionData *connData, string uriAddress){
1526         
1527         string serverAddress;
1528         
1529         // Setup the server address.
1530         
1531         if (connData->useSSL == true){
1532                 serverAddress += "https://";
1533         } else {
1534                 serverAddress += "http://";
1535         }
1536         
1537         serverAddress += connData->hostname;
1538         
1539         // Check if server port is 80, otherwise
1540         // specifiy the port number in the address.
1541         
1542         if (connData->port != 80){
1543                 serverAddress += ":";
1544                 serverAddress += to_string(connData->port);
1545         }
1546         
1547         serverAddress += uriAddress;
1548         
1549         return serverAddress;
1550         
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