#include "CalDAV.h"
+using namespace std;
+
+size_t CalDAVReceive(char *ReceivedBuffer, size_t Size, size_t NewMemoryBytes, string *StringPointer)
+{
+
+ string ReceivedBufferString = "";
+ ReceivedBufferString.append(ReceivedBuffer, NewMemoryBytes);
+
+ StringPointer->append(ReceivedBufferString);
+
+ return Size * NewMemoryBytes;
+
+}
+
+size_t CalDAVSend(char *SendBuffer, size_t Size, size_t NewMemoryBytes, void *DataStruct){
+
+ struct CalDAVSendData *UploadPtr = (struct CalDAVSendData *)DataStruct;
+
+ if (UploadPtr->sizeleft){
+
+ UploadPtr->sizeleft--;
+ char CharSend;
+
+ CharSend = (*UploadPtr->readptr)[UploadPtr->seek];
+
+ *SendBuffer = CharSend;
+
+ UploadPtr->seek++;
+
+ return 1;
+
+ }
+
+ return 0;
+
+}
+
+CalDAV::CalDAV(){
+
+ // Setup the objects within the CalDAV connection
+ // object.
+
+ ConnectionHandle = curl_easy_init();
+
+}
+
+CalDAV::~CalDAV(){
+
+ // Destory the objects within the CalDAV connection
+ // object.
+
+ curl_easy_cleanup(ConnectionHandle);
+ ConnectionHandle = nullptr;
+
+}
+
+void CalDAV::SetupConnectionData(CalDAVConnectionData *ConnData){
+
+ // Check if ConnData is a nullptr, return if it is.
+
+ if (ConnData == nullptr){
+ return;
+ }
+
+ // Set the connection settings to the values from ConnData.
+
+ ConnectionData = (*ConnData);
+
+}
+
+CalDAVStatus CalDAV::GetConnectionData(){
+
+ // Get the current connection settings for the CalDAV
+ // connection object and return a CalDAVStatus object.
+
+ CalDAVStatus ConnectionStatus;
+
+ ConnectionStatus.Hostname = ConnectionData.Hostname;
+ ConnectionStatus.Port = ConnectionData.Port;
+ ConnectionStatus.Username = ConnectionData.Username;
+ ConnectionStatus.Prefix = ConnectionData.Prefix;
+ ConnectionStatus.UseSSL = ConnectionData.UseSSL;
+ ConnectionStatus.Timeout = ConnectionData.Timeout;
+
+ return ConnectionStatus;
+
+}
+
+CalDAVServerResult CalDAV::Connect(){
+
+ CalDAVServerResult ServerResult;
+
+ string ServerAddress = "";
+ string ServerUserPass = "";
+
+ // Setup the server address.
+
+ ServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+
+ // Setup the server password.
+
+ ServerUserPass += ConnectionData.Username;
+ ServerUserPass += ":";
+ ServerUserPass += ConnectionData.Password;
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, ServerAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_USERPWD, ServerUserPass.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_TIMEOUT, ConnectionData.Timeout);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEFUNCTION, CalDAVReceive);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEDATA, &ServerData);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEHEADER, &ServerHeader);
+
+ // Connect to the CalDAV server.
+
+ ServerResult.Code = curl_easy_perform(ConnectionHandle);
+
+ // Process the result received from the server.
+
+ if (ServerResult.Code != CURLE_OK){
+
+ ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+
+ } else {
+
+ ServerResult.Result = CALDAVQUERYRESULT_OK;
+
+ }
+
+ // Get the HTTP code.
+
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
+
+ return ServerResult;
+
+}
+
+CalDAVServerResult CalDAV::GetServerResult(){
+
+ return ConnectionServerResult;
+
+}
+
+CalDAVServerSupport CalDAV::GetServerSupport(){
+
+ CalDAVServerSupport ServerStatus;
+
+ // Setup the server connection.
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "OPTIONS");
+
+ CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
+
+ // Set the results.
+
+ if (ServerResult == CURLE_OK){
+ ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
+ } else {
+ ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ ConnectionServerResult.Code = ServerResult;
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
+
+ if (ServerResult != CURLE_OK){
+ return ServerStatus;
+ }
+
+ // Check that the server header has data in,
+ // otherwise return an "empty" CalDAVServerSupport.
+
+ if (ServerHeader.size() == 0){
+ return ServerStatus;
+ }
+
+ // Process each line looking for the first DAV header
+ // line.
+
+ bool NewlineMode = true;
+
+ string DAVLine;
+
+ for (int CharSeek = 0; CharSeek < ServerHeader.size(); CharSeek++){
+
+ if (NewlineMode == true){
+
+ // Check if we have reached the end of the string.
+
+ if (CharSeek >= ServerHeader.size()){
+
+ break;
+
+ }
+
+ // Check the first four letters to make sure
+ // they are 'DAV:'.
+
+ string DAVHeaderCheck = "";
+
+ try {
+ DAVHeaderCheck = ServerHeader.substr(CharSeek, 4);
+ }
+
+ catch (out_of_range &oor){
+ break;
+ }
+
+ if (DAVHeaderCheck == "DAV:"){
+
+ CharSeek += 5;
+
+ for (; CharSeek < ServerHeader.size(); CharSeek++){
+
+ if (ServerHeader[CharSeek] == '\n'){
+
+ break;
+
+ }
+
+ DAVLine.push_back(ServerHeader[CharSeek]);
+
+ }
+
+ break;
+
+ }
+
+ NewlineMode = false;
+
+ }
+
+ if (ServerHeader[CharSeek] == '\n'){
+
+ NewlineMode = true;
+
+ }
+
+ }
+
+ // Process the DAV line.
+
+ vector<string> DAVLineData;
+ string DAVSegmentString;
+
+ for (int CharSeek = 0; CharSeek < DAVLine.size(); CharSeek++){
+
+ if (DAVLine[CharSeek] == ' '){
+ continue;
+ }
+
+ if (DAVLine[CharSeek] == ','){
+
+ DAVLineData.push_back(DAVSegmentString);
+ DAVSegmentString.clear();
+ continue;
+
+ }
+
+ DAVSegmentString += DAVLine[CharSeek];
+
+ }
+
+ // Process the DAV values and set each value
+ // to true as required.
+
+ for (int DAVItemSeek = 0;
+ DAVItemSeek < DAVLineData.size();
+ DAVItemSeek++){
+
+ if (DAVLineData.at(DAVItemSeek) == "calendar-access"){
+
+ ServerStatus.BasicSupport = true;
+
+ }
+
+ }
+
+ // Reset the connection status.
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+
+ return ServerStatus;
+
+}
+
+string CalDAV::GetUserPrincipal(){
+
+ string CurrentUserPrincipal = "";
+ string UserPrincipalRequest = "";
+ CalDAVSendData UserPrincipalSendData;
+
+ UserPrincipalRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<d:propfind xmlns:d=\"DAV:\">\n"
+ " <d:prop>\n"
+ " <d:current-user-principal />\n"
+ " </d:prop>\n"
+ "</d:propfind>";
+
+ UserPrincipalSendData.readptr = &UserPrincipalRequest;
+ UserPrincipalSendData.sizeleft = UserPrincipalRequest.size();
+
+ // Setup the header.
+
+ struct curl_slist *UserPrincipalRequestHeader = NULL;
+
+ UserPrincipalRequestHeader = curl_slist_append(UserPrincipalRequestHeader, "Depth: 0");
+ UserPrincipalRequestHeader = curl_slist_append(UserPrincipalRequestHeader, "Prefer: return-minimal");
+ UserPrincipalRequestHeader = curl_slist_append(UserPrincipalRequestHeader, "Content-Type: application/xml; charset=utf-8");
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, UserPrincipalRequestHeader);
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &UserPrincipalSendData);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ ServerData.clear();
+ ServerHeader.clear();
+
+ CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
+
+ // Set the results.
+
+ if (ServerResult == CURLE_OK){
+ ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
+ } else {
+ ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ ConnectionServerResult.Code = ServerResult;
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
+
+ if (ServerResult != CURLE_OK){
+
+ return CurrentUserPrincipal;
+
+ }
+
+ // Process the User Principal from the ServerData.
+
+ CurrentUserPrincipal = ProcessXMLUserPrincipal();
+
+ // Reset the changed settings.
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
+
+ return CurrentUserPrincipal;
+
+}
+
+string CalDAV::GetCalendarHome(string UserPrincipalURI){
+
+ string CalendarHomeURI = "";
+
+ // Build the Calendar Home URL address.
+
+ string CalendarHomeURL = BuildServerAddress(&ConnectionData, UserPrincipalURI);
+
+ // Setup the header request.
+
+ CalDAVSendData CalendarHomeSendData;
+
+ string CalendarHomeRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<d:propfind xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
+ " <d:prop>\n"
+ " <c:calendar-home-set />\n"
+ " </d:prop>\n"
+ "</d:propfind>";
+
+ CalendarHomeSendData.readptr = &CalendarHomeRequest;
+ CalendarHomeSendData.sizeleft = CalendarHomeRequest.size();
+
+ // Setup the header.
+
+ struct curl_slist *CalendarRequestHeader = NULL;
+
+ CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Depth: 0");
+ CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Prefer: return-minimal");
+ CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Content-Type: application/xml; charset=utf-8");
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarHomeURL.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &CalendarHomeSendData);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ ServerData.clear();
+ ServerHeader.clear();
+
+ CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
+
+ // Set the results.
+
+ if (ServerResult == CURLE_OK){
+ ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
+ } else {
+ ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ ConnectionServerResult.Code = ServerResult;
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
+
+ if (ServerResult != CURLE_OK){
+
+ return CalendarHomeURI;
+
+ }
+
+ // Process the User Principal from the ServerData.
+
+ CalendarHomeURI = ProcessXMLCalendarHome();
+
+ // Reset the changed settings.
+
+ string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL);
+
+ return CalendarHomeURI;
+
+}
+
+CalDAVCalendarList CalDAV::GetCalendars(){
+
+ CalDAVCalendarList ServerList;
+ CalDAVSendData CalendarListSendData;
+
+ // Build the server address.
+
+ string UserPrincipalURI = "";
+ UserPrincipalURI = GetUserPrincipal();
+
+ if (UserPrincipalURI.size() == 0){
+
+ return ServerList;
+
+ }
+
+ string CalendarHomeURI = "";
+ CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
+
+ string CalendarListURLAddress = BuildServerAddress(&ConnectionData, CalendarHomeURI);
+
+ string CalendarListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<d:propfind xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+ " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+ " <d:prop>\n"
+ " <d:resourcetype />\n"
+ " <d:displayname />\n"
+ " <d:sync-token />\n"
+ " <x0:calendar-color />\n"
+ " <x0:calendar-order />\n"
+ " <cs:getctag />\n"
+ " <c:supported-calendar-component-set />\n"
+ " <c:calendar-description />\n"
+ " </d:prop>\n"
+ "</d:propfind>";
+
+ CalendarListSendData.readptr = &CalendarListRequest;
+ CalendarListSendData.sizeleft = CalendarListRequest.size();
+
+ // Setup the header.
+
+ struct curl_slist *CalendarListRequestHeader = NULL;
+
+ CalendarListRequestHeader = curl_slist_append(CalendarListRequestHeader, "Depth: 1");
+ CalendarListRequestHeader = curl_slist_append(CalendarListRequestHeader, "Prefer: return-minimal");
+ CalendarListRequestHeader = curl_slist_append(CalendarListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarListRequestHeader);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarListURLAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &CalendarListSendData);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ ServerData.clear();
+ ServerHeader.clear();
+
+ CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
+
+ //ServerList = ProcessXMLCalendarList();
+
+ if (ServerResult == CURLE_OK){
+ ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
+ } else {
+ ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ ConnectionServerResult.Code = ServerResult;
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
+
+ if (ServerResult != CURLE_OK){
+
+ return ServerList;
+
+ }
+
+ // Process the received XML data into a list of calendars
+ // and locations.
+
+ ServerList = ProcessXMLCalendarList();
+
+ // Restore the original settings.
+
+ string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
+
+ return ServerList;
+
+}
+
+CalDAVEntryList CalDAV::GetEntryList(string *CalendarHREF){
+
+ CalDAVEntryList EntryList;
+ CalDAVSendData EntryListSendData;
+
+ if (CalendarHREF->size() == 0){
+
+ return EntryList;
+
+ }
+
+ string EntryListURLAddress = BuildServerAddress(&ConnectionData, *CalendarHREF);
+
+ string EntryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+
+ /*if (CalendarTag == nullptr){*/
+
+ EntryListRequest += "<c:calendar-query xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+ " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+ " <d:prop>\n"
+ " <d:getetag />\n"
+ " <c:calendar-data />\n"
+ " </d:prop>\n"
+ " <c:filter>\n"
+ " <c:comp-filter name=\"VCALENDAR\" />\n"
+ " </c:filter>\n"
+ "</c:calendar-query>";
+
+ /*} else {
+
+ EntryListRequest += "<d:sync-collection xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+ " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+ " <d:sync-token>";
+ EntryListRequest += *CalendarTag;
+ EntryListRequest += "</d:sync-token>\n"
+ " <d:sync-level>1</d:sync-level>\n"
+ " <d:prop>\n"
+ " <d:getetag />\n"
+ " <c:calendar-data />\n"
+ " </d:prop>\n"
+ "</d:sync-collection>";
+
+ }*/
+
+ EntryListSendData.readptr = &EntryListRequest;
+ EntryListSendData.sizeleft = EntryListRequest.size();
+
+ struct curl_slist *EntryListRequestHeader = NULL;
+
+ EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+
+ /*if (CalendarTag != nullptr){
+
+ EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+ EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+
+ }*/
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, EntryListRequestHeader);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryListURLAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryListSendData);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ ServerData.clear();
+ ServerHeader.clear();
+
+ CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
+
+ //ServerList = ProcessXMLCalendarList();
+
+ if (ServerResult == CURLE_OK){
+ ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
+ } else {
+ ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ ConnectionServerResult.Code = ServerResult;
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
+
+ if (ServerResult != CURLE_OK){
+
+ return EntryList;
+
+ }
+
+ // Process the received XML data into a list of calendars
+ // and locations.
+
+ EntryList = ProcessXMLEntryList();
+
+ // Restore the original settings.
+
+ string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
+
+ return EntryList;
+
+}
+
+CalDAVEntryList CalDAV::GetEntryList(string *CalendarHREF, string *CalendarTag){
+
+ CalDAVEntryList EntryList;
+ CalDAVSendData EntryListSendData;
+
+ if (CalendarHREF->size() == 0){
+
+ return EntryList;
+
+ }
+
+ string EntryListURLAddress = BuildServerAddress(&ConnectionData, *CalendarHREF);
+
+ // First query: Get the list of contacts that need to be updated.
+
+ string EntryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+
+ EntryListRequest += "<d:sync-collection xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
+ " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+ " <d:sync-token>";
+
+ if (CalendarTag != nullptr){
+
+ EntryListRequest += *CalendarTag;
+
+ } else {
+
+ EntryListRequest += "";
+
+ }
+
+ EntryListRequest += "</d:sync-token>\n"
+ " <d:sync-level>1</d:sync-level>\n"
+ " <d:prop>\n"
+ " <d:getetag />\n"
+ " </d:prop>\n"
+ "</d:sync-collection>";
+
+ EntryListSendData.readptr = &EntryListRequest;
+ EntryListSendData.sizeleft = EntryListRequest.size();
+
+ struct curl_slist *EntryListRequestHeader = NULL;
+
+ EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, EntryListRequestHeader);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryListURLAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryListSendData);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ ServerData.clear();
+ ServerHeader.clear();
+
+ CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
+
+ if (ServerResult == CURLE_OK){
+ ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
+ } else {
+ ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ ConnectionServerResult.Code = ServerResult;
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
+
+ if (ServerResult != CURLE_OK){
+
+ return EntryList;
+
+ }
+
+ EntryList = ProcessXMLSyncTokenList();
+
+ // Check the last entry matches the HREF and if it
+ // does then delete it.
+
+ if (EntryList.HREF.size() > 0) {
+
+ if (EntryList.HREF.rbegin()->second == *CalendarHREF){
+
+ EntryList.HREF.erase((EntryList.HREF.size() - 1));
+ EntryList.Tag.erase((EntryList.HREF.size() - 1));
+ EntryList.Data.erase((EntryList.HREF.size() - 1));
+
+ }
+
+ }
+
+ // Build the list into a new list for getting the new
+ // calendar data with.
+
+ EntryListRequest.clear();
+
+ EntryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+
+ EntryListRequest += "<c:calendar-multiget xmlns:d=\"DAV:\" "
+ " xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
+ " <d:prop>\n"
+ " <d:getetag />\n"
+ " <c:calendar-data />\n"
+ " </d:prop>\n";
+
+ for (std::map<int,string>::iterator HREFIter = EntryList.HREF.begin();
+ HREFIter != EntryList.HREF.end(); HREFIter++){
+
+ string EntryListHREFString = HREFIter->second;
+
+ EntryListRequest += " <d:href>";
+ EntryListRequest += EntryListHREFString;
+ EntryListRequest += "</d:href>\n";
+
+ }
+
+ EntryListRequest += "</c:calendar-multiget>";
+
+ CalDAVSendData UpdatedEntryListSendData;
+
+ UpdatedEntryListSendData.readptr = &EntryListRequest;
+ UpdatedEntryListSendData.sizeleft = EntryListRequest.size();
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, EntryListRequestHeader);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryListURLAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &UpdatedEntryListSendData);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Get the updated calendar data.
+
+ ServerData.clear();
+ ServerHeader.clear();
+ EntryList.HREF.clear();
+ EntryList.Tag.clear();
+ EntryList.Data.clear();
+
+ ServerResult = curl_easy_perform(ConnectionHandle);
+
+ // Check the last entry matches the HREF and if it
+ // does then delete it.
+
+ if (ServerResult == CURLE_OK){
+ ConnectionServerResult.Result = CALDAVQUERYRESULT_OK;
+ } else {
+ ConnectionServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ ConnectionServerResult.Code = ServerResult;
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ConnectionServerResult.HTTPCode);
+
+ if (ServerResult != CURLE_OK){
+
+ return EntryList;
+
+ }
+
+ EntryList = ProcessXMLEntryList();
+
+ // Second query: Get the list of contact data for the contacts that have
+ // beenchanged.
+
+ // Restore the original settings.
+
+ string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
+
+ return EntryList;
+
+}
+
+CalDAVServerResult CalDAV::AddCalendar(string CalendarName){
+
+ CalDAVServerResult ServerResult;
+
+ AddCalendar(&CalendarName, nullptr);
+
+ return ServerResult;
+
+}
+
+CalDAVServerResult CalDAV::AddCalendar(string *CalendarName, string *CalendarShortName){
+
+ CalDAVServerResult ServerResult;
+ CalDAVSendData CalendarAddSendData;
+
+ // Build the server address.
+
+ string UserPrincipalURI = "";
+ UserPrincipalURI = GetUserPrincipal();
+
+ if (UserPrincipalURI.size() == 0){
+
+ return ServerResult;
+
+ }
+
+ string CalendarHomeURI = "";
+ CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
+
+ // Generate the UUID.
+
+ string UUIDValue = "";
+
+ if (CalendarShortName == nullptr){
+
+ UUIDValue = GenerateUUID();
+ UUIDValue.erase(UUIDValue.end()-1);
+
+ } else {
+
+ UUIDValue = *CalendarShortName;
+
+ }
+
+ string CalendarHomeURL = CalendarHomeURI;
+ CalendarHomeURL.append(UUIDValue);
+ CalendarHomeURL.append("/");
+
+ // Build the calendar list address.
+
+ string CalendarListURLAddress = BuildServerAddress(&ConnectionData, CalendarHomeURL);
+
+ string CalendarAddRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<c:mkcalendar xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
+ " <d:set>\n"
+ " <d:prop>\n"
+ " <d:displayname>";
+ CalendarAddRequest += *CalendarName;
+ CalendarAddRequest += "</d:displayname>\n"
+ " <c:supported-calendar-component-set>\n"
+ " <c:comp name=\"VTODO\"/>\n"
+ " <c:comp name=\"VEVENT\"/>\n"
+ " </c:supported-calendar-component-set>\n"
+ " </d:prop>\n"
+ " </d:set>\n"
+ "</c:mkcalendar>";
+
+ CalendarAddSendData.readptr = &CalendarAddRequest;
+ CalendarAddSendData.sizeleft = CalendarAddRequest.size();
+
+ // Setup the header.
+
+ struct curl_slist *CalendarRequestHeader = NULL;
+
+ //curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarListURLAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "MKCALENDAR");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &CalendarAddSendData);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ ServerData.clear();
+ ServerHeader.clear();
+
+ CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
+
+ if (ServerConnectionResult == CURLE_OK){
+ ServerResult.Result = CALDAVQUERYRESULT_OK;
+ } else {
+ ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ ServerResult.Code = ServerConnectionResult;
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
+
+ // Restore the original settings.
+
+ string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
+
+ return ServerResult;
+
+}
+
+CalDAVServerResult CalDAV::EditCalendarProcess(string *CalendarHREF,
+ string *CalendarName,
+ Colour *CalendarColour,
+ string *CalendarDescription,
+ int *CalendarOrder){
+
+ CalDAVServerResult ServerResult;
+ CalDAVSendData CalendarEditSendData;
+
+ // Build the server address.
+
+ string UserPrincipalURI = "";
+ UserPrincipalURI = GetUserPrincipal();
+
+ if (UserPrincipalURI.size() == 0){
+
+ return ServerResult;
+
+ }
+
+ string CalendarHomeURI = "";
+ CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
+
+ // Generate the UUID.
+
+ string UUIDValue = GenerateUUID();
+ UUIDValue.erase(UUIDValue.end()-1);
+
+ string CalendarHomeURL = CalendarHomeURI;
+ CalendarHomeURL.append(UUIDValue);
+ CalendarHomeURL.append("/");
+
+ // Build the calendar list address.
+
+ string CalendarEditURLAddress = BuildServerAddress(&ConnectionData, (*CalendarHREF));
+
+ string CalendarEditRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<d:propertyupdate xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\"\n"
+ " xmlns:x0=\"http://apple.com/ns/ical/\">\n"
+ " <d:set>\n"
+ " <d:prop>\n";
+
+ // Update the calendar name.
+
+ if (CalendarName != nullptr){
+
+ CalendarEditRequest += "<d:displayname>";
+ CalendarEditRequest += (*CalendarName);
+ CalendarEditRequest += "</d:displayname>\n";
+
+ }
+
+ // Update the calendar colour.
+
+ if (CalendarColour != nullptr){
+
+ CalendarEditRequest += "<x0:calendar-color>";
+ CalendarEditRequest += (*CalendarColour);
+ CalendarEditRequest += "</x0:calendar-color>\n";
+
+ }
+
+ // Update the calendar description.
+
+ if (CalendarDescription != nullptr){
+
+ CalendarEditRequest += "<c:calendar-description>";
+ CalendarEditRequest += (*CalendarDescription);
+ CalendarEditRequest += "</c:calendar-description>\n";
+
+ }
+
+ // Update the calendar order.
+
+ if (CalendarOrder != nullptr){
+
+ CalendarEditRequest += "<x0:calendar-order>";
+ CalendarEditRequest += to_string((*CalendarOrder));
+ CalendarEditRequest += "</x0:calendar-order>\n";
+
+ }
+
+ CalendarEditRequest += " </d:prop>\n"
+ " </d:set>\n"
+ "</d:propertyupdate>";
+
+ CalendarEditSendData.readptr = &CalendarEditRequest;
+ CalendarEditSendData.sizeleft = CalendarEditRequest.size();
+
+ // Setup the header.
+
+ struct curl_slist *CalendarRequestHeader = NULL;
+
+ //curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarEditURLAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PROPPATCH");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &CalendarEditSendData);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ ServerData.clear();
+ ServerHeader.clear();
+
+ CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
+
+ if (ServerConnectionResult == CURLE_OK){
+ ServerResult.Result = CALDAVQUERYRESULT_OK;
+ } else {
+ ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ ServerResult.Code = ServerConnectionResult;
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
+
+ // Restore the original settings.
+
+ string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
+
+ return ServerResult;
+
+}
+
+CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF,
+ string *CalendarName,
+ Colour *CalendarColour,
+ string *CalendarDescription,
+ int *CalendarOrder){
+
+ CalDAVServerResult ServerResult;
+
+ ServerResult = EditCalendarProcess(CalendarHREF,
+ CalendarName,
+ CalendarColour,
+ CalendarDescription,
+ CalendarOrder);
+
+ return ServerResult;
+
+}
+
+CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF,
+ Colour *CalendarColour){
+
+
+ CalDAVServerResult ServerResult;
+
+ ServerResult = EditCalendarProcess(CalendarHREF,
+ nullptr,
+ CalendarColour,
+ nullptr,
+ nullptr);
+
+ return ServerResult;
+
+}
+
+CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF,
+ string *CalendarName){
+
+ CalDAVServerResult ServerResult;
+
+ ServerResult = EditCalendarProcess(CalendarHREF,
+ CalendarName,
+ nullptr,
+ nullptr,
+ nullptr);
+
+ return ServerResult;
+
+}
+
+CalDAVServerResult CalDAV::EditCalendar(string *CalendarHREF,
+ int *CalendarOrder){
+
+ CalDAVServerResult ServerResult;
+
+ ServerResult = EditCalendarProcess(CalendarHREF,
+ nullptr,
+ nullptr,
+ nullptr,
+ CalendarOrder);
+
+ return ServerResult;
+
+}
+
+CalDAVServerResult CalDAV::EditCalendarDescription(string *CalendarHREF,
+ string *CalendarDescription){
+
+ CalDAVServerResult ServerResult;
+
+ ServerResult = EditCalendarProcess(CalendarHREF,
+ nullptr,
+ nullptr,
+ CalendarDescription,
+ nullptr);
+
+ return ServerResult;
+
+}
+
+CalDAVServerResult CalDAV::DeleteCalendar(string *CalendarHREF){
+
+ CalDAVServerResult ServerResult;
+
+ // Build the server address.
+
+ string UserPrincipalURI = "";
+ UserPrincipalURI = GetUserPrincipal();
+
+ if (UserPrincipalURI.size() == 0){
+
+ return ServerResult;
+
+ }
+
+ string CalendarHomeURI = "";
+ CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
+
+ // Generate the UUID.
+
+ string UUIDValue = GenerateUUID();
+ UUIDValue.erase(UUIDValue.end()-1);
+
+ string CalendarHomeURL = CalendarHomeURI;
+ CalendarHomeURL.append(UUIDValue);
+ CalendarHomeURL.append("/");
+
+ // Build the calendar list address.
+
+ struct curl_slist *DeleteRequestHeader = NULL;
+
+ DeleteRequestHeader = curl_slist_append(DeleteRequestHeader, "Depth: infinity");
+
+ string CalendarDeleteURLAddress = BuildServerAddress(&ConnectionData, (*CalendarHREF));
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, DeleteRequestHeader);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, CalendarDeleteURLAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
+
+ // Delete the calendar.
+
+ ServerData.clear();
+ ServerHeader.clear();
+
+ CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
+
+ if (ServerConnectionResult == CURLE_OK){
+ ServerResult.Result = CALDAVQUERYRESULT_OK;
+ } else {
+ ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ ServerResult.Code = ServerConnectionResult;
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
+
+ // Restore the original settings.
+
+ string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL);
+
+ return ServerResult;
+
+}
+
+CalDAVServerResult CalDAV::GetEntryETag(string *CalendarEntryHREF, string *ETagValue){
+
+ CalDAVServerResult ServerResult;
+ CalDAVSendData EntryETagGetData;
+
+ // Build the server address.
+
+ string UserPrincipalURI = "";
+ UserPrincipalURI = GetUserPrincipal();
+
+ if (UserPrincipalURI.size() == 0){
+
+ return ServerResult;
+
+ }
+
+ string CalendarHomeURI = "";
+ CalendarHomeURI = GetCalendarHome(UserPrincipalURI);
+
+ // Split the path and filename.
+
+ string EntryURIPath;
+ string EntryFilename;
+
+ SplitPathFilename(CalendarEntryHREF, &EntryURIPath, &EntryFilename);
+
+ // Build the request for the server.
+
+ string EntryETagRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<c:calendar-multiget xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
+ " <d:prop>\n"
+ " <d:getetag />\n"
+ " </d:prop>\n"
+ " <d:href>";
+ EntryETagRequest += (*CalendarEntryHREF);
+ EntryETagRequest += "</d:href>\n"
+ "</c:calendar-multiget>";
+
+ EntryETagGetData.readptr = &EntryETagRequest;
+ EntryETagGetData.sizeleft = EntryETagRequest.size();
+
+ // Build the calendar list address.
+
+ struct curl_slist *GetETagRequestHeader = NULL;
+
+ GetETagRequestHeader = curl_slist_append(GetETagRequestHeader, "Depth: 1");
+ GetETagRequestHeader = curl_slist_append(GetETagRequestHeader, "Prefer: return-minimal");
+ GetETagRequestHeader = curl_slist_append(GetETagRequestHeader, "Content-Type: application/xml; charset=utf-8");
+
+ string GetETagURLAddress = BuildServerAddress(&ConnectionData, EntryURIPath);
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, GetETagRequestHeader);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, GetETagURLAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryETagGetData);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Attempt to get the entity tag.
+
+ ServerData.clear();
+ ServerHeader.clear();
+
+ CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
+
+ if (ServerConnectionResult == CURLE_OK){
+ ServerResult.Result = CALDAVQUERYRESULT_OK;
+ } else {
+ ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ ServerResult.Code = ServerConnectionResult;
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
+
+ if (ServerConnectionResult != CURLE_OK){
+ return ServerResult;
+ }
+
+ // Get the entity tag from the result.
+
+ *ETagValue = ProcessXMLEntryETag();
+
+ // Restore the original settings.
+
+ string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL);
+
+ return ServerResult;
+
+}
+
+CalDAVServerResult CalDAV::AddEntry(string *CalendarEntryHREF, string *EntryData){
+
+ // Add an entry to the calendar collection.
+
+ CalDAVServerResult ServerResult;
+ CalDAVSendData EntryAddSendData;
+
+ // Build the calendar list address.
+
+ string EntryAddURLAddress = BuildServerAddress(&ConnectionData, (*CalendarEntryHREF));
+
+ EntryAddSendData.readptr = EntryData;
+ EntryAddSendData.sizeleft = EntryData->size();
+
+ struct curl_slist *CalendarRequestHeader = NULL;
+
+ CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Content-Type: text/calendar; charset=utf-8");
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryAddURLAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PUT");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryAddSendData);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ ServerData.clear();
+ ServerHeader.clear();
+
+ CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
+
+ if (ServerConnectionResult == CURLE_OK){
+ ServerResult.Result = CALDAVQUERYRESULT_OK;
+ } else {
+ ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ ServerResult.Code = ServerConnectionResult;
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
+
+ // Restore the original settings.
+
+ string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL);
+
+ return ServerResult;
+
+}
+
+CalDAVServerResult CalDAV::EditEntry(string *CalendarEntryHREF, string *EntryData, string *EntryETag){
+
+ // Edit an entry in the calendar collection.
+
+ // Add an entry to the calendar collection.
+
+ CalDAVServerResult ServerResult;
+ CalDAVSendData EntryAddSendData;
+
+ // Build the calendar list address.
+
+ string EntryAddURLAddress = BuildServerAddress(&ConnectionData, (*CalendarEntryHREF));
+
+ EntryAddSendData.readptr = EntryData;
+ EntryAddSendData.sizeleft = EntryData->size();
+
+ string IfMatchHeader = "If-Match: \"";
+ IfMatchHeader.append(*EntryETag);
+ IfMatchHeader.append("\"");
+
+ struct curl_slist *CalendarRequestHeader = NULL;
+
+ CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, "Content-Type: text/calendar; charset=utf-8");
+ CalendarRequestHeader = curl_slist_append(CalendarRequestHeader, IfMatchHeader.c_str());
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryAddURLAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "PUT");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, &EntryAddSendData);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
+
+ // Process the data.
+
+ ServerData.clear();
+ ServerHeader.clear();
+
+ CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
+
+ if (ServerConnectionResult == CURLE_OK){
+ ServerResult.Result = CALDAVQUERYRESULT_OK;
+ } else {
+ ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ ServerResult.Code = ServerConnectionResult;
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
+
+ // Restore the original settings.
+
+ string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL);
+
+ return ServerResult;
+
+}
+
+CalDAVServerResult CalDAV::DeleteEntry(string *CalendarEntryHREF){
+
+ // Delete an entry in the calendar collection.
+
+ CalDAVServerResult ServerResult;
+
+ // Build the calendar list address.
+
+ string EntryDeleteURLAddress = BuildServerAddress(&ConnectionData, (*CalendarEntryHREF));
+
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, EntryDeleteURLAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
+
+ // Delete the calendar.
+
+ ServerData.clear();
+ ServerHeader.clear();
+
+ CURLcode ServerConnectionResult = curl_easy_perform(ConnectionHandle);
+
+ if (ServerConnectionResult == CURLE_OK){
+ ServerResult.Result = CALDAVQUERYRESULT_OK;
+ } else {
+ ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
+ }
+ ServerResult.Code = ServerConnectionResult;
+ curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
+
+ // Restore the original settings.
+
+ string OriginalServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
+ curl_easy_setopt(ConnectionHandle, CURLOPT_URL, OriginalServerAddress.c_str());
+ curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_READFUNCTION, NULL);
+ curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, NULL);
+
+ return ServerResult;
+
+}
+
bool CalDAVObjectValidSettings(CalDAVConnectionData *ConnData){
// Check if the passed CalDAV Connection Data is has
// Check the server hostname. Return false
// if no value has been set.
- if (ConnData->Hostname.size() > 0){
+ if (ConnData->Hostname.size() == 0){
return false;
// Check the server username. Return false
// if no value has been set.
-
- if (ConnData->Username.size() > 0){
+
+ if (ConnData->Username.size() == 0){
+
return false;
- }
-
+
+ }
+
// Check the server password. Return false
// if no value has been set.
-
- if (ConnData->Password.size() > 0){
+
+ if (ConnData->Password.size() == 0){
+
return false;
+
}
// Cannot check UseSSL: It is either true
return true;
+}
+
+string BuildServerAddress(CalDAVConnectionData *ConnData, string URIAddress){
+
+ string ServerAddress;
+
+ // Setup the server address.
+
+ if (ConnData->UseSSL == true){
+ ServerAddress += "https://";
+ } else {
+ ServerAddress += "http://";
+ }
+
+ ServerAddress += ConnData->Hostname;
+
+ // Check if server port is 80, otherwise
+ // specifiy the port number in the address.
+
+ if (ConnData->Port != 80){
+ ServerAddress += ":";
+ ServerAddress += to_string(ConnData->Port);
+ }
+
+ ServerAddress += URIAddress;
+
+ return ServerAddress;
+
}
\ No newline at end of file