1 // CalDAV.cpp - CalDAV Connection Object.
3 // (c) 2016-2017 Xestia Software Development.
5 // This file is part of Xestia Calendar.
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.
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.
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/>
23 size_t CalDAVReceive(char *ReceivedBuffer, size_t Size, size_t NewMemoryBytes, string *StringPointer)
26 StringPointer->append(ReceivedBuffer, NewMemoryBytes);
28 return Size * NewMemoryBytes;
32 size_t CalDAVSend(char *SendBuffer, size_t Size, size_t NewMemoryBytes, void *DataStruct){
34 struct CalDAVSendData *UploadPtr = (struct CalDAVSendData *)DataStruct;
36 if (UploadPtr->sizeleft){
38 UploadPtr->sizeleft--;
41 CharSend = (*UploadPtr->readptr)[UploadPtr->seek];
43 *SendBuffer = CharSend;
57 // Setup the objects within the CalDAV connection
60 ConnectionHandle = curl_easy_init();
66 // Destory the objects within the CalDAV connection
69 curl_easy_cleanup(ConnectionHandle);
70 ConnectionHandle = nullptr;
74 void CalDAV::SetupConnectionData(CalDAVConnectionData *ConnData){
76 // Check if ConnData is a nullptr, return if it is.
78 if (ConnData == nullptr){
82 // Set the connection settings to the values from ConnData.
84 ConnectionData = (*ConnData);
88 CalDAVStatus CalDAV::GetConnectionData(){
90 // Get the current connection settings for the CalDAV
91 // connection object and return a CalDAVStatus object.
93 CalDAVStatus ConnectionStatus;
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;
102 return ConnectionStatus;
106 CalDAVServerResult CalDAV::Connect(){
108 CalDAVServerResult ServerResult;
110 string ServerAddress = "";
111 string ServerUserPass = "";
113 // Setup the server address.
115 ServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
117 // Setup the server password.
119 ServerUserPass += ConnectionData.Username;
120 ServerUserPass += ":";
121 ServerUserPass += ConnectionData.Password;
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);
132 // Connect to the CalDAV server.
134 ServerResult.Code = curl_easy_perform(ConnectionHandle);
136 // Process the result received from the server.
138 if (ServerResult.Code != CURLE_OK){
140 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
144 ServerResult.Result = CALDAVQUERYRESULT_OK;
148 // Get the HTTP code.
150 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
156 CalDAVServerResult CalDAV::GetServerResult(){
158 return ConnectionServerResult;
162 CalDAVServerSupport CalDAV::GetServerSupport(){
164 CalDAVServerSupport ServerStatus;
166 // Setup the server connection.
168 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "OPTIONS");
170 CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
174 if (ServerResult == CURLE_OK){
175 ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
177 ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
179 ConnectionServerResult.Code = ServerResult;
180 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
182 if (ServerResult != CURLE_OK){
186 // Check that the server header has data in,
187 // otherwise return an "empty" CalDAVServerSupport.
189 if (ServerHeader.size() == 0){
193 // Process each line looking for the first DAV header
196 bool NewlineMode = true;
200 for (int CharSeek = 0; CharSeek < ServerHeader.size(); CharSeek++){
202 if (NewlineMode == true){
204 // Check if we have reached the end of the string.
206 if (CharSeek >= ServerHeader.size()){
212 // Check the first four letters to make sure
215 string DAVHeaderCheck = "";
218 DAVHeaderCheck = ServerHeader.substr(CharSeek, 4);
221 catch (out_of_range &oor){
225 if (DAVHeaderCheck == "DAV:"){
229 for (; CharSeek < ServerHeader.size(); CharSeek++){
231 if (ServerHeader[CharSeek] == '\n'){
237 DAVLine.push_back(ServerHeader[CharSeek]);
249 if (ServerHeader[CharSeek] == '\n'){
257 // Process the DAV line.
259 vector<string> DAVLineData;
260 string DAVSegmentString;
262 for (int CharSeek = 0; CharSeek < DAVLine.size(); CharSeek++){
264 if (DAVLine[CharSeek] == ' '){
268 if (DAVLine[CharSeek] == ','){
270 DAVLineData.push_back(DAVSegmentString);
271 DAVSegmentString.clear();
276 DAVSegmentString += DAVLine[CharSeek];
280 // Process the DAV values and set each value
281 // to true as required.
283 for (int DAVItemSeek = 0;
284 DAVItemSeek < DAVLineData.size();
287 if (DAVLineData.at(DAVItemSeek) == "calendar-access"){
289 ServerStatus.BasicSupport = true;
295 // Reset the connection status.
297 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
303 string CalDAV::GetUserPrincipal(){
305 string CurrentUserPrincipal = "";
306 string UserPrincipalRequest = "";
307 CalDAVSendData UserPrincipalSendData;
309 UserPrincipalRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
310 "<d:propfind xmlns:d=\"DAV:\">\n"
312 " <d:current-user-principal />\n"
316 UserPrincipalSendData.readptr = &UserPrincipalRequest;
317 UserPrincipalSendData.sizeleft = UserPrincipalRequest.size();
321 struct curl_slist *UserPrincipalRequestHeader = NULL;
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");
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);
337 ServerHeader.clear();
339 CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
343 if (ServerResult == CURLE_OK){
344 ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
346 ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
348 ConnectionServerResult.Code = ServerResult;
349 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
351 if (ServerResult != CURLE_OK){
353 return CurrentUserPrincipal;
357 // Process the User Principal from the ServerData.
359 CurrentUserPrincipal = ProcessXMLUserPrincipal();
361 // Reset the changed settings.
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){
373 string CalendarHomeURI = "";
375 // Build the Calendar Home URL address.
377 string CalendarHomeURL = BuildServerAddress(&ConnectionData, UserPrincipalURI);
379 // Setup the header request.
381 CalDAVSendData CalendarHomeSendData;
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"
386 " <c:calendar-home-set />\n"
390 CalendarHomeSendData.readptr = &CalendarHomeRequest;
391 CalendarHomeSendData.sizeleft = CalendarHomeRequest.size();
395 struct curl_slist *CalendarRequestHeader = NULL;
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");
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);
411 ServerHeader.clear();
413 CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
417 if (ServerResult == CURLE_OK){
418 ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
420 ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
422 ConnectionServerResult.Code = ServerResult;
423 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
425 if (ServerResult != CURLE_OK){
427 return CalendarHomeURI;
431 // Process the User Principal from the ServerData.
433 CalendarHomeURI = ProcessXMLCalendarHome();
435 // Reset the changed settings.
437 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
438 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
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);
445 return CalendarHomeURI;
449 CalDAVCalendarList CalDAV::GetCalendars(){
451 CalDAVCalendarList ServerList;
452 CalDAVSendData CalendarListSendData;
454 // Build the server address.
456 string UserPrincipalURI = "";
457 UserPrincipalURI = GetUserPrincipal();
459 if (UserPrincipalURI.size() == 0){
465 string CalendarHomeURI = "";
466 CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
468 string CalendarListURLAddress = BuildServerAddress(&ConnectionData, CalendarHomeURI);
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"
474 " <d:resourcetype />\n"
475 " <d:displayname />\n"
476 " <d:sync-token />\n"
477 " <x0:calendar-color />\n"
478 " <x0:calendar-order />\n"
480 " <c:supported-calendar-component-set />\n"
481 " <c:calendar-description />\n"
485 CalendarListSendData.readptr = &CalendarListRequest;
486 CalendarListSendData.sizeleft = CalendarListRequest.size();
490 struct curl_slist *CalendarListRequestHeader = NULL;
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");
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);
506 ServerHeader.clear();
508 CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
510 //ServerList = ProcessXMLCalendarList();
512 if (ServerResult == CURLE_OK){
513 ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
515 ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
517 ConnectionServerResult.Code = ServerResult;
518 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
520 if (ServerResult != CURLE_OK){
526 // Process the received XML data into a list of calendars
529 ServerList = ProcessXMLCalendarList();
531 // Restore the original settings.
533 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
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);
545 CalDAVEntryList CalDAV::GetEntryList(string *CalendarHREF){
547 CalDAVEntryList EntryList;
548 CalDAVSendData EntryListSendData;
550 if (CalendarHREF->size() == 0){
556 string EntryListURLAddress = BuildServerAddress(&ConnectionData, *CalendarHREF);
558 string EntryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
560 /*if (CalendarTag == nullptr){*/
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"
566 " <c:calendar-data />\n"
569 " <c:comp-filter name=\"VCALENDAR\" />\n"
571 "</c:calendar-query>";
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"
578 EntryListRequest += *CalendarTag;
579 EntryListRequest += "</d:sync-token>\n"
580 " <d:sync-level>1</d:sync-level>\n"
583 " <c:calendar-data />\n"
585 "</d:sync-collection>";
589 EntryListSendData.readptr = &EntryListRequest;
590 EntryListSendData.sizeleft = EntryListRequest.size();
592 struct curl_slist *EntryListRequestHeader = NULL;
594 EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
596 /*if (CalendarTag != nullptr){
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");
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);
613 ServerHeader.clear();
615 CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
617 //ServerList = ProcessXMLCalendarList();
619 if (ServerResult == CURLE_OK){
620 ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
622 ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
624 ConnectionServerResult.Code = ServerResult;
625 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
627 if (ServerResult != CURLE_OK){
633 // Process the received XML data into a list of calendars
636 EntryList = ProcessXMLEntryList();
638 // Restore the original settings.
640 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
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);
652 CalDAVEntryList CalDAV::GetEntryList(string *CalendarHREF, string *CalendarTag){
654 CalDAVEntryList EntryList;
655 CalDAVSendData EntryListSendData;
657 if (CalendarHREF->size() == 0){
663 string EntryListURLAddress = BuildServerAddress(&ConnectionData, *CalendarHREF);
665 // First query: Get the list of contacts that need to be updated.
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"
673 if (CalendarTag != nullptr){
675 EntryListRequest += *CalendarTag;
679 EntryListRequest += "";
683 EntryListRequest += "</d:sync-token>\n"
684 " <d:sync-level>1</d:sync-level>\n"
688 "</d:sync-collection>";
690 EntryListSendData.readptr = &EntryListRequest;
691 EntryListSendData.sizeleft = EntryListRequest.size();
693 struct curl_slist *EntryListRequestHeader = NULL;
695 EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
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);
707 ServerHeader.clear();
709 CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
711 if (ServerResult == CURLE_OK){
712 ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
714 ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
716 ConnectionServerResult.Code = ServerResult;
717 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
719 if (ServerResult != CURLE_OK){
725 EntryList = ProcessXMLSyncTokenList();
727 // Check the last entry matches the HREF and if it
728 // does then delete it.
730 if (EntryList.HREF.size() > 0) {
732 if (EntryList.HREF.rbegin()->second == *CalendarHREF){
734 EntryList.HREF.erase((EntryList.HREF.size() - 1));
735 EntryList.Tag.erase((EntryList.HREF.size() - 1));
736 EntryList.Data.erase((EntryList.HREF.size() - 1));
742 // Build the list into a new list for getting the new
743 // calendar data with.
745 EntryListRequest.clear();
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"
753 " <c:calendar-data />\n"
756 for (std::map<int,string>::iterator HREFIter = EntryList.HREF.begin();
757 HREFIter != EntryList.HREF.end(); HREFIter++){
759 string EntryListHREFString = HREFIter->second;
761 EntryListRequest += " <d:href>";
762 EntryListRequest += EntryListHREFString;
763 EntryListRequest += "</d:href>\n";
767 EntryListRequest += "</c:calendar-multiget>";
769 CalDAVSendData UpdatedEntryListSendData;
771 UpdatedEntryListSendData.readptr = &EntryListRequest;
772 UpdatedEntryListSendData.sizeleft = EntryListRequest.size();
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);
781 // Get the updated calendar data.
784 ServerHeader.clear();
785 EntryList.HREF.clear();
786 EntryList.Tag.clear();
787 EntryList.Data.clear();
789 ServerResult = curl_easy_perform(ConnectionHandle);
791 // Check the last entry matches the HREF and if it
792 // does then delete it.
794 if (ServerResult == CURLE_OK){
795 ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
797 ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
799 ConnectionServerResult.Code = ServerResult;
800 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
802 if (ServerResult != CURLE_OK){
808 EntryList = ProcessXMLEntryList();
810 // Second query: Get the list of contact data for the contacts that have
813 // Restore the original settings.
815 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
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);
827 CalDAVServerResult CalDAV::AddCalendar(string CalendarName){
829 CalDAVServerResult ServerResult;
831 AddCalendar(&CalendarName, nullptr);
837 CalDAVServerResult CalDAV::AddCalendar(string *CalendarName, string *CalendarShortName){
839 CalDAVServerResult ServerResult;
840 CalDAVSendData CalendarAddSendData;
842 // Build the server address.
844 string UserPrincipalURI = "";
845 UserPrincipalURI = GetUserPrincipal();
847 if (UserPrincipalURI.size() == 0){
853 string CalendarHomeURI = "";
854 CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
856 // Generate the UUID.
858 string UUIDValue = "";
860 if (CalendarShortName == nullptr){
862 UUIDValue = GenerateUUID();
863 UUIDValue.erase(UUIDValue.end()-1);
867 UUIDValue = *CalendarShortName;
871 string CalendarHomeURL = CalendarHomeURI;
872 CalendarHomeURL.append(UUIDValue);
873 CalendarHomeURL.append("/");
875 // Build the calendar list address.
877 string CalendarListURLAddress = BuildServerAddress(&ConnectionData, CalendarHomeURL);
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"
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"
894 CalendarAddSendData.readptr = &CalendarAddRequest;
895 CalendarAddSendData.sizeleft = CalendarAddRequest.size();
899 struct curl_slist *CalendarRequestHeader = NULL;
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);
911 ServerHeader.clear();
913 CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
915 if (ServerConnectionResult == CURLE_OK){
916 ServerResult.Result = CALDAVQUERYRESULT_OK;
918 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
920 ServerResult.Code = ServerConnectionResult;
921 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
923 // Restore the original settings.
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);
936 CalDAVServerResult CalDAV::EditCalendarProcess(string *CalendarHREF,
937 string *CalendarName,
938 Colour *CalendarColour,
939 string *CalendarDescription,
942 CalDAVServerResult ServerResult;
943 CalDAVSendData CalendarEditSendData;
945 // Build the server address.
947 string UserPrincipalURI = "";
948 UserPrincipalURI = GetUserPrincipal();
950 if (UserPrincipalURI.size() == 0){
956 string CalendarHomeURI = "";
957 CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
959 // Generate the UUID.
961 string UUIDValue = GenerateUUID();
962 UUIDValue.erase(UUIDValue.end()-1);
964 string CalendarHomeURL = CalendarHomeURI;
965 CalendarHomeURL.append(UUIDValue);
966 CalendarHomeURL.append("/");
968 // Build the calendar list address.
970 string CalendarEditURLAddress = BuildServerAddress(&ConnectionData, (*CalendarHREF));
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"
978 // Update the calendar name.
980 if (CalendarName != nullptr){
982 CalendarEditRequest += "<d:displayname>";
983 CalendarEditRequest += (*CalendarName);
984 CalendarEditRequest += "</d:displayname>\n";
988 // Update the calendar colour.
990 if (CalendarColour != nullptr){
992 CalendarEditRequest += "<x0:calendar-color>";
993 CalendarEditRequest += (*CalendarColour);
994 CalendarEditRequest += "</x0:calendar-color>\n";
998 // Update the calendar description.
1000 if (CalendarDescription != nullptr){
1002 CalendarEditRequest += "<c:calendar-description>";
1003 CalendarEditRequest += (*CalendarDescription);
1004 CalendarEditRequest += "</c:calendar-description>\n";
1008 // Update the calendar order.
1010 if (CalendarOrder != nullptr){
1012 CalendarEditRequest += "<x0:calendar-order>";
1013 CalendarEditRequest += to_string((*CalendarOrder));
1014 CalendarEditRequest += "</x0:calendar-order>\n";
1018 CalendarEditRequest += " </d:prop>\n"
1020 "</d:propertyupdate>";
1022 CalendarEditSendData.readptr = &CalendarEditRequest;
1023 CalendarEditSendData.sizeleft = CalendarEditRequest.size();
1025 // Setup the header.
1027 struct curl_slist *CalendarRequestHeader = NULL;
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);
1036 // Process the data.
1039 ServerHeader.clear();
1041 CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
1043 if (ServerConnectionResult == CURLE_OK){
1044 ServerResult.Result = CALDAVQUERYRESULT_OK;
1046 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
1048 ServerResult.Code = ServerConnectionResult;
1049 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
1051 // Restore the original settings.
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);
1060 return ServerResult;
1064 CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF,
1065 string *CalendarName,
1066 Colour *CalendarColour,
1067 string *CalendarDescription,
1068 int *CalendarOrder){
1070 CalDAVServerResult ServerResult;
1072 ServerResult = EditCalendarProcess(CalendarHREF,
1075 CalendarDescription,
1078 return ServerResult;
1082 CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF,
1083 Colour *CalendarColour){
1086 CalDAVServerResult ServerResult;
1088 ServerResult = EditCalendarProcess(CalendarHREF,
1094 return ServerResult;
1098 CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF,
1099 string *CalendarName){
1101 CalDAVServerResult ServerResult;
1103 ServerResult = EditCalendarProcess(CalendarHREF,
1109 return ServerResult;
1113 CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF,
1114 int *CalendarOrder){
1116 CalDAVServerResult ServerResult;
1118 ServerResult = EditCalendarProcess(CalendarHREF,
1124 return ServerResult;
1128 CalDAVServerResult CalDAV::EditCalendarDescription(string *CalendarHREF,
1129 string *CalendarDescription){
1131 CalDAVServerResult ServerResult;
1133 ServerResult = EditCalendarProcess(CalendarHREF,
1136 CalendarDescription,
1139 return ServerResult;
1143 CalDAVServerResult CalDAV::DeleteCalendar(string *CalendarHREF){
1145 CalDAVServerResult ServerResult;
1147 // Build the server address.
1149 string UserPrincipalURI = "";
1150 UserPrincipalURI = GetUserPrincipal();
1152 if (UserPrincipalURI.size() == 0){
1154 return ServerResult;
1158 string CalendarHomeURI = "";
1159 CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
1161 // Generate the UUID.
1163 string UUIDValue = GenerateUUID();
1164 UUIDValue.erase(UUIDValue.end()-1);
1166 string CalendarHomeURL = CalendarHomeURI;
1167 CalendarHomeURL.append(UUIDValue);
1168 CalendarHomeURL.append("/");
1170 // Build the calendar list address.
1172 struct curl_slist *DeleteRequestHeader = NULL;
1174 DeleteRequestHeader = curl_slist_append(DeleteRequestHeader, "Depth: infinity");
1176 string CalendarDeleteURLAddress = BuildServerAddress(&ConnectionData, (*CalendarHREF));
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");
1182 // Delete the calendar.
1185 ServerHeader.clear();
1187 CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
1189 if (ServerConnectionResult == CURLE_OK){
1190 ServerResult.Result = CALDAVQUERYRESULT_OK;
1192 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
1194 ServerResult.Code = ServerConnectionResult;
1195 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
1197 // Restore the original settings.
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);
1207 return ServerResult;
1211 CalDAVServerResult CalDAV::GetEntryETag(string *CalendarEntryHREF, string *ETagValue){
1213 CalDAVServerResult ServerResult;
1214 CalDAVSendData EntryETagGetData;
1216 // Build the server address.
1218 string UserPrincipalURI = "";
1219 UserPrincipalURI = GetUserPrincipal();
1221 if (UserPrincipalURI.size() == 0){
1223 return ServerResult;
1227 string CalendarHomeURI = "";
1228 CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
1230 // Split the path and filename.
1232 string EntryURIPath;
1233 string EntryFilename;
1235 SplitPathFilename(CalendarEntryHREF, &EntryURIPath, &EntryFilename);
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"
1245 EntryETagRequest += (*CalendarEntryHREF);
1246 EntryETagRequest += "</d:href>\n"
1247 "</c:calendar-multiget>";
1249 EntryETagGetData.readptr = &EntryETagRequest;
1250 EntryETagGetData.sizeleft = EntryETagRequest.size();
1252 // Build the calendar list address.
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");
1260 string GetETagURLAddress = BuildServerAddress(&ConnectionData, EntryURIPath);
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);
1269 // Attempt to get the entity tag.
1272 ServerHeader.clear();
1274 CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
1276 if (ServerConnectionResult == CURLE_OK){
1277 ServerResult.Result = CALDAVQUERYRESULT_OK;
1279 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
1281 ServerResult.Code = ServerConnectionResult;
1282 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
1284 if (ServerConnectionResult != CURLE_OK){
1285 return ServerResult;
1288 // Get the entity tag from the result.
1290 *ETagValue = ProcessXMLEntryETag();
1292 // Restore the original settings.
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);
1302 return ServerResult;
1306 CalDAVServerResult CalDAV::AddEntry(string *CalendarEntryHREF, string *EntryData){
1308 // Add an entry to the calendar collection.
1310 CalDAVServerResult ServerResult;
1311 CalDAVSendData EntryAddSendData;
1313 // Build the calendar list address.
1315 string EntryAddURLAddress = BuildServerAddress(&ConnectionData, (*CalendarEntryHREF));
1317 EntryAddSendData.readptr = EntryData;
1318 EntryAddSendData.sizeleft = EntryData->size();
1320 struct curl_slist *CalendarRequestHeader = NULL;
1322 CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Content-Type: text/calendar; charset=utf-8");
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);
1331 // Process the data.
1334 ServerHeader.clear();
1336 CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
1338 if (ServerConnectionResult == CURLE_OK){
1339 ServerResult.Result = CALDAVQUERYRESULT_OK;
1341 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
1343 ServerResult.Code = ServerConnectionResult;
1344 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
1346 // Restore the original settings.
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);
1356 return ServerResult;
1360 CalDAVServerResult CalDAV::EditEntry(string *CalendarEntryHREF, string *EntryData, string *EntryETag){
1362 // Edit an entry in the calendar collection.
1364 // Add an entry to the calendar collection.
1366 CalDAVServerResult ServerResult;
1367 CalDAVSendData EntryAddSendData;
1369 // Build the calendar list address.
1371 string EntryAddURLAddress = BuildServerAddress(&ConnectionData, (*CalendarEntryHREF));
1373 EntryAddSendData.readptr = EntryData;
1374 EntryAddSendData.sizeleft = EntryData->size();
1376 string IfMatchHeader = "If-Match: \"";
1377 IfMatchHeader.append(*EntryETag);
1378 IfMatchHeader.append("\"");
1380 struct curl_slist *CalendarRequestHeader = NULL;
1382 CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Content-Type: text/calendar; charset=utf-8");
1383 CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, IfMatchHeader.c_str());
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);
1392 // Process the data.
1395 ServerHeader.clear();
1397 CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
1399 if (ServerConnectionResult == CURLE_OK){
1400 ServerResult.Result = CALDAVQUERYRESULT_OK;
1402 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
1404 ServerResult.Code = ServerConnectionResult;
1405 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
1407 // Restore the original settings.
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);
1417 return ServerResult;
1421 CalDAVServerResult CalDAV::DeleteEntry(string *CalendarEntryHREF){
1423 // Delete an entry in the calendar collection.
1425 CalDAVServerResult ServerResult;
1427 // Build the calendar list address.
1429 string EntryDeleteURLAddress = BuildServerAddress(&ConnectionData, (*CalendarEntryHREF));
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");
1435 // Delete the calendar.
1438 ServerHeader.clear();
1440 CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
1442 if (ServerConnectionResult == CURLE_OK){
1443 ServerResult.Result = CALDAVQUERYRESULT_OK;
1445 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
1447 ServerResult.Code = ServerConnectionResult;
1448 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
1450 // Restore the original settings.
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);
1460 return ServerResult;
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){
1475 // Check the server hostname. Return false
1476 // if no value has been set.
1478 if (ConnData->Hostname.size() == 0){
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.
1488 if (ConnData->Port < 1 || ConnData->Port > 65535){
1494 // Check the server username. Return false
1495 // if no value has been set.
1497 if (ConnData->Username.size() == 0){
1503 // Check the server password. Return false
1504 // if no value has been set.
1506 if (ConnData->Password.size() == 0){
1512 // Cannot check UseSSL: It is either true
1515 // Cannot check Prefix: The prefix may need
1516 // to be worked out first.
1518 // No errors were found whilst checking so
1525 string BuildServerAddress(CalDAVConnectionData *ConnData, string URIAddress){
1527 string ServerAddress;
1529 // Setup the server address.
1531 if (ConnData->UseSSL == true){
1532 ServerAddress += "https://";
1534 ServerAddress += "http://";
1537 ServerAddress += ConnData->Hostname;
1539 // Check if server port is 80, otherwise
1540 // specifiy the port number in the address.
1542 if (ConnData->Port != 80){
1543 ServerAddress += ":";
1544 ServerAddress += to_string(ConnData->Port);
1547 ServerAddress += URIAddress;
1549 return ServerAddress;