1 // CalDAV.cpp - CalDAV Connection Object.
3 // (c) 2016 Xestia Software Development.
5 // This file is part of Xestia Calendar.
7 // Xestia Address Book is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
11 // Xestia Address Book is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
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 string ReceivedBufferString = "";
27 ReceivedBufferString.append(ReceivedBuffer, NewMemoryBytes);
29 StringPointer->append(ReceivedBufferString);
31 return Size * NewMemoryBytes;
35 size_t CalDAVSend(char *SendBuffer, size_t Size, size_t NewMemoryBytes, void *DataStruct){
37 struct CalDAVSendData *UploadPtr = (struct CalDAVSendData *)DataStruct;
39 if (UploadPtr->sizeleft){
41 UploadPtr->sizeleft--;
44 CharSend = (*UploadPtr->readptr)[UploadPtr->seek];
46 *SendBuffer = CharSend;
60 // Setup the objects within the CalDAV connection
63 ConnectionHandle = curl_easy_init();
69 // Destory the objects within the CalDAV connection
72 curl_easy_cleanup(ConnectionHandle);
73 ConnectionHandle = nullptr;
77 void CalDAV::SetupConnectionData(CalDAVConnectionData *ConnData){
79 // Check if ConnData is a nullptr, return if it is.
81 if (ConnData == nullptr){
85 // Set the connection settings to the values from ConnData.
87 ConnectionData = (*ConnData);
91 CalDAVStatus CalDAV::GetConnectionData(){
93 // Get the current connection settings for the CalDAV
94 // connection object and return a CalDAVStatus object.
96 CalDAVStatus ConnectionStatus;
98 ConnectionStatus.Hostname = ConnectionData.Hostname;
99 ConnectionStatus.Port = ConnectionData.Port;
100 ConnectionStatus.Username = ConnectionData.Username;
101 ConnectionStatus.Prefix = ConnectionData.Prefix;
102 ConnectionStatus.UseSSL = ConnectionData.UseSSL;
103 ConnectionStatus.Timeout = ConnectionData.Timeout;
105 return ConnectionStatus;
109 CalDAVServerResult CalDAV::Connect(){
111 CalDAVServerResult ServerResult;
113 string ServerAddress = "";
114 string ServerUserPass = "";
116 // Setup the server address.
118 ServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
120 // Setup the server password.
122 ServerUserPass += ConnectionData.Username;
123 ServerUserPass += ":";
124 ServerUserPass += ConnectionData.Password;
126 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, ServerAddress.c_str());
127 curl_easy_setopt(ConnectionHandle, CURLOPT_USERPWD, ServerUserPass.c_str());
128 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
129 curl_easy_setopt(ConnectionHandle, CURLOPT_FAILONERROR, 1L);
130 curl_easy_setopt(ConnectionHandle, CURLOPT_TIMEOUT, ConnectionData.Timeout);
131 curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEFUNCTION, CalDAVReceive);
132 curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEDATA, &ServerData);
133 curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEHEADER, &ServerHeader);
135 // Connect to the CalDAV server.
137 ServerResult.Code = curl_easy_perform(ConnectionHandle);
139 // Process the result received from the server.
141 if (ServerResult.Code != CURLE_OK){
143 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
147 ServerResult.Result = CALDAVQUERYRESULT_OK;
151 // Get the HTTP code.
153 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
159 CalDAVServerResult CalDAV::GetServerResult(){
161 return ConnectionServerResult;
165 CalDAVServerSupport CalDAV::GetServerSupport(){
167 CalDAVServerSupport ServerStatus;
169 // Setup the server connection.
171 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "OPTIONS");
173 CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
177 if (ServerResult == CURLE_OK){
178 ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
180 ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
182 ConnectionServerResult.Code = ServerResult;
183 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
185 if (ServerResult != CURLE_OK){
189 // Check that the server header has data in,
190 // otherwise return an "empty" CalDAVServerSupport.
192 if (ServerHeader.size() == 0){
196 // Process each line looking for the first DAV header
199 bool NewlineMode = true;
203 for (int CharSeek = 0; CharSeek < ServerHeader.size(); CharSeek++){
205 if (NewlineMode == true){
207 // Check if we have reached the end of the string.
209 if (CharSeek >= ServerHeader.size()){
215 // Check the first four letters to make sure
218 string DAVHeaderCheck = "";
221 DAVHeaderCheck = ServerHeader.substr(CharSeek, 4);
224 catch (out_of_range &oor){
228 if (DAVHeaderCheck == "DAV:"){
232 for (; CharSeek < ServerHeader.size(); CharSeek++){
234 if (ServerHeader[CharSeek] == '\n'){
240 DAVLine.push_back(ServerHeader[CharSeek]);
252 if (ServerHeader[CharSeek] == '\n'){
260 // Process the DAV line.
262 vector<string> DAVLineData;
263 string DAVSegmentString;
265 for (int CharSeek = 0; CharSeek < DAVLine.size(); CharSeek++){
267 if (DAVLine[CharSeek] == ' '){
271 if (DAVLine[CharSeek] == ','){
273 DAVLineData.push_back(DAVSegmentString);
274 DAVSegmentString.clear();
279 DAVSegmentString += DAVLine[CharSeek];
283 // Process the DAV values and set each value
284 // to true as required.
286 for (int DAVItemSeek = 0;
287 DAVItemSeek < DAVLineData.size();
290 if (DAVLineData.at(DAVItemSeek) == "calendar-access"){
292 ServerStatus.BasicSupport = true;
298 // Reset the connection status.
300 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
306 string CalDAV::GetUserPrincipal(){
308 string CurrentUserPrincipal = "";
309 string UserPrincipalRequest = "";
310 CalDAVSendData UserPrincipalSendData;
312 UserPrincipalRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
313 "<d:propfind xmlns:d=\"DAV:\">\n"
315 " <d:current-user-principal />\n"
319 UserPrincipalSendData.readptr = &UserPrincipalRequest;
320 UserPrincipalSendData.sizeleft = UserPrincipalRequest.size();
324 struct curl_slist *UserPrincipalRequestHeader = NULL;
326 UserPrincipalRequestHeader = curl_slist_append(UserPrincipalRequestHeader, "Depth: 0");
327 UserPrincipalRequestHeader = curl_slist_append(UserPrincipalRequestHeader, "Prefer: return-minimal");
328 UserPrincipalRequestHeader = curl_slist_append(UserPrincipalRequestHeader, "Content-Type: application/xml; charset=utf-8");
330 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, UserPrincipalRequestHeader);
332 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
333 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
334 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &UserPrincipalSendData);
335 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
340 ServerHeader.clear();
342 CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
346 if (ServerResult == CURLE_OK){
347 ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
349 ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
351 ConnectionServerResult.Code = ServerResult;
352 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
354 if (ServerResult != CURLE_OK){
356 return CurrentUserPrincipal;
360 // Process the User Principal from the ServerData.
362 CurrentUserPrincipal = ProcessXMLUserPrincipal();
364 // Reset the changed settings.
366 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
367 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
368 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
370 return CurrentUserPrincipal;
374 string CalDAV::GetCalendarHome(string UserPrincipalURI){
376 string CalendarHomeURI = "";
378 // Build the Calendar Home URL address.
380 string CalendarHomeURL = BuildServerAddress(&ConnectionData, UserPrincipalURI);
382 // Setup the header request.
384 CalDAVSendData CalendarHomeSendData;
386 string CalendarHomeRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
387 "<d:propfind xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
389 " <c:calendar-home-set />\n"
393 CalendarHomeSendData.readptr = &CalendarHomeRequest;
394 CalendarHomeSendData.sizeleft = CalendarHomeRequest.size();
398 struct curl_slist *CalendarRequestHeader = NULL;
400 CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Depth: 0");
401 CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Prefer: return-minimal");
402 CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Content-Type: application/xml; charset=utf-8");
404 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
405 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarHomeURL.c_str());
406 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
407 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
408 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &CalendarHomeSendData);
409 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
414 ServerHeader.clear();
416 CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
420 if (ServerResult == CURLE_OK){
421 ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
423 ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
425 ConnectionServerResult.Code = ServerResult;
426 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
428 if (ServerResult != CURLE_OK){
430 return CalendarHomeURI;
434 // Process the User Principal from the ServerData.
436 CalendarHomeURI = ProcessXMLCalendarHome();
438 // Reset the changed settings.
440 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
441 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
443 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
444 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
445 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
446 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL);
448 return CalendarHomeURI;
452 CalDAVCalendarList CalDAV::GetCalendars(){
454 CalDAVCalendarList ServerList;
455 CalDAVSendData CalendarListSendData;
457 // Build the server address.
459 string UserPrincipalURI = "";
460 UserPrincipalURI = GetUserPrincipal();
462 if (UserPrincipalURI.size() == 0){
468 string CalendarHomeURI = "";
469 CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
471 string CalendarListURLAddress = BuildServerAddress(&ConnectionData, CalendarHomeURI);
473 string CalendarListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
474 "<d:propfind xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
475 " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
477 " <d:resourcetype />\n"
478 " <d:displayname />\n"
479 " <d:sync-token />\n"
480 " <x0:calendar-color />\n"
481 " <x0:calendar-order />\n"
483 " <c:supported-calendar-component-set />\n"
484 " <c:calendar-description />\n"
488 CalendarListSendData.readptr = &CalendarListRequest;
489 CalendarListSendData.sizeleft = CalendarListRequest.size();
493 struct curl_slist *CalendarListRequestHeader = NULL;
495 CalendarListRequestHeader = curl_slist_append(CalendarListRequestHeader, "Depth: 1");
496 CalendarListRequestHeader = curl_slist_append(CalendarListRequestHeader, "Prefer: return-minimal");
497 CalendarListRequestHeader = curl_slist_append(CalendarListRequestHeader, "Content-Type: application/xml; charset=utf-8");
499 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarListRequestHeader);
500 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarListURLAddress.c_str());
501 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
502 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
503 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &CalendarListSendData);
504 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
509 ServerHeader.clear();
511 CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
513 //ServerList = ProcessXMLCalendarList();
515 if (ServerResult == CURLE_OK){
516 ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
518 ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
520 ConnectionServerResult.Code = ServerResult;
521 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
523 if (ServerResult != CURLE_OK){
529 // Process the received XML data into a list of calendars
532 ServerList = ProcessXMLCalendarList();
534 // Restore the original settings.
536 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
538 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
539 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
540 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
541 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
542 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
548 CalDAVEntryList CalDAV::GetEntryList(string *CalendarHREF){
550 CalDAVEntryList EntryList;
551 CalDAVSendData EntryListSendData;
553 if (CalendarHREF->size() == 0){
559 string EntryListURLAddress = BuildServerAddress(&ConnectionData, *CalendarHREF);
561 string EntryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
563 /*if (CalendarTag == nullptr){*/
565 EntryListRequest += "<c:calendar-query xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
566 " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
569 " <c:calendar-data />\n"
572 " <c:comp-filter name=\"VCALENDAR\" />\n"
574 "</c:calendar-query>";
578 EntryListRequest += "<d:sync-collection xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
579 " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
581 EntryListRequest += *CalendarTag;
582 EntryListRequest += "</d:sync-token>\n"
583 " <d:sync-level>1</d:sync-level>\n"
586 " <c:calendar-data />\n"
588 "</d:sync-collection>";
592 EntryListSendData.readptr = &EntryListRequest;
593 EntryListSendData.sizeleft = EntryListRequest.size();
595 struct curl_slist *EntryListRequestHeader = NULL;
597 EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
599 /*if (CalendarTag != nullptr){
601 EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
602 EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
606 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, EntryListRequestHeader);
607 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryListURLAddress.c_str());
608 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
609 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
610 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryListSendData);
611 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
616 ServerHeader.clear();
618 CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
620 //ServerList = ProcessXMLCalendarList();
622 if (ServerResult == CURLE_OK){
623 ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
625 ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
627 ConnectionServerResult.Code = ServerResult;
628 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
630 if (ServerResult != CURLE_OK){
636 // Process the received XML data into a list of calendars
639 EntryList = ProcessXMLEntryList();
641 // Restore the original settings.
643 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
645 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
646 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
647 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
648 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
649 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
655 CalDAVEntryList CalDAV::GetEntryList(string *CalendarHREF, string *CalendarTag){
657 CalDAVEntryList EntryList;
658 CalDAVSendData EntryListSendData;
660 if (CalendarHREF->size() == 0){
666 string EntryListURLAddress = BuildServerAddress(&ConnectionData, *CalendarHREF);
668 // First query: Get the list of contacts that need to be updated.
670 string EntryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
672 EntryListRequest += "<d:sync-collection xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
673 " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
676 if (CalendarTag != nullptr){
678 EntryListRequest += *CalendarTag;
682 EntryListRequest += "";
686 EntryListRequest += "</d:sync-token>\n"
687 " <d:sync-level>1</d:sync-level>\n"
691 "</d:sync-collection>";
693 EntryListSendData.readptr = &EntryListRequest;
694 EntryListSendData.sizeleft = EntryListRequest.size();
696 struct curl_slist *EntryListRequestHeader = NULL;
698 EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
700 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, EntryListRequestHeader);
701 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryListURLAddress.c_str());
702 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
703 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
704 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryListSendData);
705 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
710 ServerHeader.clear();
712 CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
714 if (ServerResult == CURLE_OK){
715 ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
717 ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
719 ConnectionServerResult.Code = ServerResult;
720 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
722 if (ServerResult != CURLE_OK){
728 EntryList = ProcessXMLSyncTokenList();
730 // Check the last entry matches the HREF and if it
731 // does then delete it.
733 if (EntryList.HREF.size() > 0) {
735 if (EntryList.HREF.rbegin()->second == *CalendarHREF){
737 EntryList.HREF.erase((EntryList.HREF.size() - 1));
738 EntryList.Tag.erase((EntryList.HREF.size() - 1));
739 EntryList.Data.erase((EntryList.HREF.size() - 1));
745 // Build the list into a new list for getting the new
746 // calendar data with.
748 EntryListRequest.clear();
750 EntryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
752 EntryListRequest += "<c:calendar-multiget xmlns:d=\"DAV:\" "
753 " xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
756 " <c:calendar-data />\n"
759 for (std::map<int,string>::iterator HREFIter = EntryList.HREF.begin();
760 HREFIter != EntryList.HREF.end(); HREFIter++){
762 string EntryListHREFString = HREFIter->second;
764 EntryListRequest += " <d:href>";
765 EntryListRequest += EntryListHREFString;
766 EntryListRequest += "</d:href>\n";
770 EntryListRequest += "</c:calendar-multiget>";
772 CalDAVSendData UpdatedEntryListSendData;
774 UpdatedEntryListSendData.readptr = &EntryListRequest;
775 UpdatedEntryListSendData.sizeleft = EntryListRequest.size();
777 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, EntryListRequestHeader);
778 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryListURLAddress.c_str());
779 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
780 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
781 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &UpdatedEntryListSendData);
782 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
784 // Get the updated calendar data.
787 ServerHeader.clear();
788 EntryList.HREF.clear();
789 EntryList.Tag.clear();
790 EntryList.Data.clear();
792 ServerResult = curl_easy_perform(ConnectionHandle);
794 // Check the last entry matches the HREF and if it
795 // does then delete it.
797 if (ServerResult == CURLE_OK){
798 ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
800 ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
802 ConnectionServerResult.Code = ServerResult;
803 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
805 if (ServerResult != CURLE_OK){
811 EntryList = ProcessXMLEntryList();
813 // Second query: Get the list of contact data for the contacts that have
816 // Restore the original settings.
818 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
820 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
821 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
822 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
823 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
824 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
830 CalDAVServerResult CalDAV::AddCalendar(string CalendarName){
832 CalDAVServerResult ServerResult;
834 AddCalendar(&CalendarName, nullptr);
840 CalDAVServerResult CalDAV::AddCalendar(string *CalendarName, string *CalendarShortName){
842 CalDAVServerResult ServerResult;
843 CalDAVSendData CalendarAddSendData;
845 // Build the server address.
847 string UserPrincipalURI = "";
848 UserPrincipalURI = GetUserPrincipal();
850 if (UserPrincipalURI.size() == 0){
856 string CalendarHomeURI = "";
857 CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
859 // Generate the UUID.
861 string UUIDValue = "";
863 if (CalendarShortName == nullptr){
865 UUIDValue = GenerateUUID();
866 UUIDValue.erase(UUIDValue.end()-1);
870 UUIDValue = *CalendarShortName;
874 string CalendarHomeURL = CalendarHomeURI;
875 CalendarHomeURL.append(UUIDValue);
876 CalendarHomeURL.append("/");
878 // Build the calendar list address.
880 string CalendarListURLAddress = BuildServerAddress(&ConnectionData, CalendarHomeURL);
882 string CalendarAddRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
883 "<c:mkcalendar xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
887 CalendarAddRequest += *CalendarName;
888 CalendarAddRequest += "</d:displayname>\n"
889 " <c:supported-calendar-component-set>\n"
890 " <c:comp name=\"VTODO\"/>\n"
891 " <c:comp name=\"VEVENT\"/>\n"
892 " </c:supported-calendar-component-set>\n"
897 CalendarAddSendData.readptr = &CalendarAddRequest;
898 CalendarAddSendData.sizeleft = CalendarAddRequest.size();
902 struct curl_slist *CalendarRequestHeader = NULL;
904 //curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
905 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarListURLAddress.c_str());
906 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "MKCALENDAR");
907 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
908 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &CalendarAddSendData);
909 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
914 ServerHeader.clear();
916 CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
918 if (ServerConnectionResult == CURLE_OK){
919 ServerResult.Result = CALDAVQUERYRESULT_OK;
921 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
923 ServerResult.Code = ServerConnectionResult;
924 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
926 // Restore the original settings.
928 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
929 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
930 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
931 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
932 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
933 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
939 CalDAVServerResult CalDAV::EditCalendarProcess(string *CalendarHREF,
940 string *CalendarName,
941 Colour *CalendarColour,
942 string *CalendarDescription,
945 CalDAVServerResult ServerResult;
946 CalDAVSendData CalendarEditSendData;
948 // Build the server address.
950 string UserPrincipalURI = "";
951 UserPrincipalURI = GetUserPrincipal();
953 if (UserPrincipalURI.size() == 0){
959 string CalendarHomeURI = "";
960 CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
962 // Generate the UUID.
964 string UUIDValue = GenerateUUID();
965 UUIDValue.erase(UUIDValue.end()-1);
967 string CalendarHomeURL = CalendarHomeURI;
968 CalendarHomeURL.append(UUIDValue);
969 CalendarHomeURL.append("/");
971 // Build the calendar list address.
973 string CalendarEditURLAddress = BuildServerAddress(&ConnectionData, (*CalendarHREF));
975 string CalendarEditRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
976 "<d:propertyupdate xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\"\n"
977 " xmlns:x0=\"http://apple.com/ns/ical/\">\n"
981 // Update the calendar name.
983 if (CalendarName != nullptr){
985 CalendarEditRequest += "<d:displayname>";
986 CalendarEditRequest += (*CalendarName);
987 CalendarEditRequest += "</d:displayname>\n";
991 // Update the calendar colour.
993 if (CalendarColour != nullptr){
995 CalendarEditRequest += "<x0:calendar-color>";
996 CalendarEditRequest += (*CalendarColour);
997 CalendarEditRequest += "</x0:calendar-color>\n";
1001 // Update the calendar description.
1003 if (CalendarDescription != nullptr){
1005 CalendarEditRequest += "<c:calendar-description>";
1006 CalendarEditRequest += (*CalendarDescription);
1007 CalendarEditRequest += "</c:calendar-description>\n";
1011 // Update the calendar order.
1013 if (CalendarOrder != nullptr){
1015 CalendarEditRequest += "<x0:calendar-order>";
1016 CalendarEditRequest += to_string((*CalendarOrder));
1017 CalendarEditRequest += "</x0:calendar-order>\n";
1021 CalendarEditRequest += " </d:prop>\n"
1023 "</d:propertyupdate>";
1025 CalendarEditSendData.readptr = &CalendarEditRequest;
1026 CalendarEditSendData.sizeleft = CalendarEditRequest.size();
1028 // Setup the header.
1030 struct curl_slist *CalendarRequestHeader = NULL;
1032 //curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
1033 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarEditURLAddress.c_str());
1034 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PROPPATCH");
1035 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
1036 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &CalendarEditSendData);
1037 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
1039 // Process the data.
1042 ServerHeader.clear();
1044 CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
1046 if (ServerConnectionResult == CURLE_OK){
1047 ServerResult.Result = CALDAVQUERYRESULT_OK;
1049 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
1051 ServerResult.Code = ServerConnectionResult;
1052 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
1054 // Restore the original settings.
1056 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
1057 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
1058 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
1059 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
1060 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
1061 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
1063 return ServerResult;
1067 CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF,
1068 string *CalendarName,
1069 Colour *CalendarColour,
1070 string *CalendarDescription,
1071 int *CalendarOrder){
1073 CalDAVServerResult ServerResult;
1075 ServerResult = EditCalendarProcess(CalendarHREF,
1078 CalendarDescription,
1081 return ServerResult;
1085 CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF,
1086 Colour *CalendarColour){
1089 CalDAVServerResult ServerResult;
1091 ServerResult = EditCalendarProcess(CalendarHREF,
1097 return ServerResult;
1101 CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF,
1102 string *CalendarName){
1104 CalDAVServerResult ServerResult;
1106 ServerResult = EditCalendarProcess(CalendarHREF,
1112 return ServerResult;
1116 CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF,
1117 int *CalendarOrder){
1119 CalDAVServerResult ServerResult;
1121 ServerResult = EditCalendarProcess(CalendarHREF,
1127 return ServerResult;
1131 CalDAVServerResult CalDAV::EditCalendarDescription(string *CalendarHREF,
1132 string *CalendarDescription){
1134 CalDAVServerResult ServerResult;
1136 ServerResult = EditCalendarProcess(CalendarHREF,
1139 CalendarDescription,
1142 return ServerResult;
1146 CalDAVServerResult CalDAV::DeleteCalendar(string *CalendarHREF){
1148 CalDAVServerResult ServerResult;
1150 // Build the server address.
1152 string UserPrincipalURI = "";
1153 UserPrincipalURI = GetUserPrincipal();
1155 if (UserPrincipalURI.size() == 0){
1157 return ServerResult;
1161 string CalendarHomeURI = "";
1162 CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
1164 // Generate the UUID.
1166 string UUIDValue = GenerateUUID();
1167 UUIDValue.erase(UUIDValue.end()-1);
1169 string CalendarHomeURL = CalendarHomeURI;
1170 CalendarHomeURL.append(UUIDValue);
1171 CalendarHomeURL.append("/");
1173 // Build the calendar list address.
1175 struct curl_slist *DeleteRequestHeader = NULL;
1177 DeleteRequestHeader = curl_slist_append(DeleteRequestHeader, "Depth: infinity");
1179 string CalendarDeleteURLAddress = BuildServerAddress(&ConnectionData, (*CalendarHREF));
1181 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, DeleteRequestHeader);
1182 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarDeleteURLAddress.c_str());
1183 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
1185 // Delete the calendar.
1188 ServerHeader.clear();
1190 CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
1192 if (ServerConnectionResult == CURLE_OK){
1193 ServerResult.Result = CALDAVQUERYRESULT_OK;
1195 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
1197 ServerResult.Code = ServerConnectionResult;
1198 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
1200 // Restore the original settings.
1202 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
1203 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
1204 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
1205 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
1206 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
1207 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
1208 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL);
1210 return ServerResult;
1214 CalDAVServerResult CalDAV::GetEntryETag(string *CalendarEntryHREF, string *ETagValue){
1216 CalDAVServerResult ServerResult;
1217 CalDAVSendData EntryETagGetData;
1219 // Build the server address.
1221 string UserPrincipalURI = "";
1222 UserPrincipalURI = GetUserPrincipal();
1224 if (UserPrincipalURI.size() == 0){
1226 return ServerResult;
1230 string CalendarHomeURI = "";
1231 CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
1233 // Split the path and filename.
1235 string EntryURIPath;
1236 string EntryFilename;
1238 SplitPathFilename(CalendarEntryHREF, &EntryURIPath, &EntryFilename);
1240 // Build the request for the server.
1242 string EntryETagRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1243 "<c:calendar-multiget xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
1248 EntryETagRequest += (*CalendarEntryHREF);
1249 EntryETagRequest += "</d:href>\n"
1250 "</c:calendar-multiget>";
1252 EntryETagGetData.readptr = &EntryETagRequest;
1253 EntryETagGetData.sizeleft = EntryETagRequest.size();
1255 // Build the calendar list address.
1257 struct curl_slist *GetETagRequestHeader = NULL;
1259 GetETagRequestHeader = curl_slist_append(GetETagRequestHeader, "Depth: 1");
1260 GetETagRequestHeader = curl_slist_append(GetETagRequestHeader, "Prefer: return-minimal");
1261 GetETagRequestHeader = curl_slist_append(GetETagRequestHeader, "Content-Type: application/xml; charset=utf-8");
1263 string GetETagURLAddress = BuildServerAddress(&ConnectionData, EntryURIPath);
1265 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, GetETagRequestHeader);
1266 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, GetETagURLAddress.c_str());
1267 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
1268 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
1269 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryETagGetData);
1270 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
1272 // Attempt to get the entity tag.
1275 ServerHeader.clear();
1277 CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
1279 if (ServerConnectionResult == CURLE_OK){
1280 ServerResult.Result = CALDAVQUERYRESULT_OK;
1282 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
1284 ServerResult.Code = ServerConnectionResult;
1285 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
1287 if (ServerConnectionResult != CURLE_OK){
1288 return ServerResult;
1291 // Get the entity tag from the result.
1293 *ETagValue = ProcessXMLEntryETag();
1295 // Restore the original settings.
1297 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
1298 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
1299 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
1300 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
1301 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
1302 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
1303 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL);
1305 return ServerResult;
1309 CalDAVServerResult CalDAV::AddEntry(string *CalendarEntryHREF, string *EntryData){
1311 // Add an entry to the calendar collection.
1313 CalDAVServerResult ServerResult;
1314 CalDAVSendData EntryAddSendData;
1316 // Build the calendar list address.
1318 string EntryAddURLAddress = BuildServerAddress(&ConnectionData, (*CalendarEntryHREF));
1320 EntryAddSendData.readptr = EntryData;
1321 EntryAddSendData.sizeleft = EntryData->size();
1323 struct curl_slist *CalendarRequestHeader = NULL;
1325 CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Content-Type: text/calendar; charset=utf-8");
1327 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
1328 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryAddURLAddress.c_str());
1329 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PUT");
1330 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
1331 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryAddSendData);
1332 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
1334 // Process the data.
1337 ServerHeader.clear();
1339 CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
1341 if (ServerConnectionResult == CURLE_OK){
1342 ServerResult.Result = CALDAVQUERYRESULT_OK;
1344 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
1346 ServerResult.Code = ServerConnectionResult;
1347 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
1349 // Restore the original settings.
1351 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
1352 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
1353 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
1354 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
1355 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
1356 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
1357 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL);
1359 return ServerResult;
1363 CalDAVServerResult CalDAV::EditEntry(string *CalendarEntryHREF, string *EntryData, string *EntryETag){
1365 // Edit an entry in the calendar collection.
1367 // Add an entry to the calendar collection.
1369 CalDAVServerResult ServerResult;
1370 CalDAVSendData EntryAddSendData;
1372 // Build the calendar list address.
1374 string EntryAddURLAddress = BuildServerAddress(&ConnectionData, (*CalendarEntryHREF));
1376 EntryAddSendData.readptr = EntryData;
1377 EntryAddSendData.sizeleft = EntryData->size();
1379 string IfMatchHeader = "If-Match: \"";
1380 IfMatchHeader.append(*EntryETag);
1381 IfMatchHeader.append("\"");
1383 struct curl_slist *CalendarRequestHeader = NULL;
1385 CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Content-Type: text/calendar; charset=utf-8");
1386 CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, IfMatchHeader.c_str());
1388 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
1389 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryAddURLAddress.c_str());
1390 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PUT");
1391 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
1392 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryAddSendData);
1393 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
1395 // Process the data.
1398 ServerHeader.clear();
1400 CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
1402 if (ServerConnectionResult == CURLE_OK){
1403 ServerResult.Result = CALDAVQUERYRESULT_OK;
1405 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
1407 ServerResult.Code = ServerConnectionResult;
1408 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
1410 // Restore the original settings.
1412 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
1413 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
1414 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
1415 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
1416 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
1417 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
1418 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL);
1420 return ServerResult;
1424 CalDAVServerResult CalDAV::DeleteEntry(string *CalendarEntryHREF){
1426 // Delete an entry in the calendar collection.
1428 CalDAVServerResult ServerResult;
1430 // Build the calendar list address.
1432 string EntryDeleteURLAddress = BuildServerAddress(&ConnectionData, (*CalendarEntryHREF));
1434 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL);
1435 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryDeleteURLAddress.c_str());
1436 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
1438 // Delete the calendar.
1441 ServerHeader.clear();
1443 CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
1445 if (ServerConnectionResult == CURLE_OK){
1446 ServerResult.Result = CALDAVQUERYRESULT_OK;
1448 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
1450 ServerResult.Code = ServerConnectionResult;
1451 curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
1453 // Restore the original settings.
1455 string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
1456 curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
1457 curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
1458 curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
1459 curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
1460 curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
1461 curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL);
1463 return ServerResult;
1467 bool CalDAVObjectValidSettings(CalDAVConnectionData *ConnData){
1469 // Check if the passed CalDAV Connection Data is has
1470 // an address set. Return false if nullptr is used.
1472 if (ConnData == nullptr){
1478 // Check the server hostname. Return false
1479 // if no value has been set.
1481 if (ConnData->Hostname.size() == 0){
1487 // Check the server port. Return false if
1488 // no value has been set or the port number
1489 // is less than 1 or higher than 65535.
1491 if (ConnData->Port < 1 || ConnData->Port > 65535){
1497 // Check the server username. Return false
1498 // if no value has been set.
1500 if (ConnData->Username.size() == 0){
1506 // Check the server password. Return false
1507 // if no value has been set.
1509 if (ConnData->Password.size() == 0){
1515 // Cannot check UseSSL: It is either true
1518 // Cannot check Prefix: The prefix may need
1519 // to be worked out first.
1521 // No errors were found whilst checking so
1528 string BuildServerAddress(CalDAVConnectionData *ConnData, string URIAddress){
1530 string ServerAddress;
1532 // Setup the server address.
1534 if (ConnData->UseSSL == true){
1535 ServerAddress += "https://";
1537 ServerAddress += "http://";
1540 ServerAddress += ConnData->Hostname;
1542 // Check if server port is 80, otherwise
1543 // specifiy the port number in the address.
1545 if (ConnData->Port != 80){
1546 ServerAddress += ":";
1547 ServerAddress += to_string(ConnData->Port);
1550 ServerAddress += URIAddress;
1552 return ServerAddress;