db5033470af9dcde54768d3def98897c9a284405
[siplcs.git] / src / core / sipe-ews.c
blobdb5033470af9dcde54768d3def98897c9a284405
1 /**
2 * @file sipe-ews.c
4 * pidgin-sipe
6 * Copyright (C) 2010-2013 SIPE Project <http://sipe.sourceforge.net/>
7 * Copyright (C) 2010, 2009 pier11 <pier11@operamail.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 /**
26 For communication with Exchange 2007/2010 Web Server/Web Services:
28 1) Autodiscover (HTTPS POST request). With redirect support. XML content.
29 1.1) DNS SRV record _autodiscover._tcp.<domain> may also be resolved.
30 2) Availability Web service (SOAP = HTTPS POST + XML) call.
31 3) Out of Office (OOF) Web Service (SOAP = HTTPS POST + XML) call.
32 4) Web server authentication required - NTLM and/or Negotiate (Kerberos).
34 Note: ews - EWS stands for Exchange Web Services.
36 It will be able to retrieve our Calendar information (FreeBusy, WorkingHours,
37 Meetings Subject and Location, Is_Meeting) as well as our Out of Office (OOF) note
38 from Exchange Web Services for subsequent publishing.
40 Ref. for more implementation details:
41 http://sourceforge.net/projects/sipe/forums/forum/688535/topic/3403462
43 Similar functionality for Lotus Notes/Domino, iCalendar/CalDAV/Google would
44 be great to implement too.
47 #include <string.h>
48 #include <time.h>
50 #include <glib.h>
52 #include "sipe-backend.h"
53 #include "sipe-common.h"
54 #include "sipe-cal.h"
55 #include "sipe-core.h"
56 #include "sipe-core-private.h"
57 #include "sipe-ews.h"
58 #include "sipe-http.h"
59 #include "sipe-utils.h"
60 #include "sipe-xml.h"
62 /**
63 * Autodiscover request for Exchange Web Services
64 * @param email (%s) Ex.: alice@cosmo.local
66 #define SIPE_EWS_AUTODISCOVER_REQUEST \
67 "<?xml version=\"1.0\"?>"\
68 "<Autodiscover xmlns=\"http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006\">"\
69 "<Request>"\
70 "<EMailAddress>%s</EMailAddress>"\
71 "<AcceptableResponseSchema>"\
72 "http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a"\
73 "</AcceptableResponseSchema>"\
74 "</Request>"\
75 "</Autodiscover>"
77 /**
78 * GetUserOofSettingsRequest SOAP request to Exchange Web Services
79 * to obtain our Out-of-office (OOF) information.
80 * @param email (%s) Ex.: alice@cosmo.local
82 #define SIPE_EWS_USER_OOF_SETTINGS_REQUEST \
83 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
84 "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\
85 "<soap:Body>"\
86 "<GetUserOofSettingsRequest xmlns=\"http://schemas.microsoft.com/exchange/services/2006/messages\">"\
87 "<Mailbox xmlns=\"http://schemas.microsoft.com/exchange/services/2006/types\">"\
88 "<Address>%s</Address>"\
89 "</Mailbox>"\
90 "</GetUserOofSettingsRequest>"\
91 "</soap:Body>"\
92 "</soap:Envelope>"
94 /**
95 * GetUserAvailabilityRequest SOAP request to Exchange Web Services
96 * to obtain our Availability (FreeBusy, WorkingHours, Meetings) information.
97 * @param email (%s) Ex.: alice@cosmo.local
98 * @param start_time (%s) Ex.: 2009-12-06T00:00:00
99 * @param end_time (%s) Ex.: 2009-12-09T23:59:59
101 #define SIPE_EWS_USER_AVAILABILITY_REQUEST \
102 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
103 "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
104 " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
105 " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
106 " xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\">"\
107 "<soap:Body>"\
108 "<GetUserAvailabilityRequest xmlns=\"http://schemas.microsoft.com/exchange/services/2006/messages\""\
109 " xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\">"\
110 "<t:TimeZone xmlns=\"http://schemas.microsoft.com/exchange/services/2006/types\">"\
111 "<Bias>0</Bias>"\
112 "<StandardTime>"\
113 "<Bias>0</Bias>"\
114 "<Time>00:00:00</Time>"\
115 "<DayOrder>0</DayOrder>"\
116 "<Month>0</Month>"\
117 "<DayOfWeek>Sunday</DayOfWeek>"\
118 "</StandardTime>"\
119 "<DaylightTime>"\
120 "<Bias>0</Bias>"\
121 "<Time>00:00:00</Time>"\
122 "<DayOrder>0</DayOrder>"\
123 "<Month>0</Month>"\
124 "<DayOfWeek>Sunday</DayOfWeek>"\
125 "</DaylightTime>"\
126 "</t:TimeZone>"\
127 "<MailboxDataArray>"\
128 "<t:MailboxData>"\
129 "<t:Email>"\
130 "<t:Address>%s</t:Address>"\
131 "</t:Email>"\
132 "<t:AttendeeType>Required</t:AttendeeType>"\
133 "<t:ExcludeConflicts>false</t:ExcludeConflicts>"\
134 "</t:MailboxData>"\
135 "</MailboxDataArray>"\
136 "<t:FreeBusyViewOptions>"\
137 "<t:TimeWindow>"\
138 "<t:StartTime>%s</t:StartTime>"\
139 "<t:EndTime>%s</t:EndTime>"\
140 "</t:TimeWindow>"\
141 "<t:MergedFreeBusyIntervalInMinutes>15</t:MergedFreeBusyIntervalInMinutes>"\
142 "<t:RequestedView>DetailedMerged</t:RequestedView>"\
143 "</t:FreeBusyViewOptions>"\
144 "</GetUserAvailabilityRequest>"\
145 "</soap:Body>"\
146 "</soap:Envelope>"
148 #define SIPE_EWS_STATE_NONE 0
149 #define SIPE_EWS_STATE_AUTODISCOVER_SUCCESS 1
150 #define SIPE_EWS_STATE_AUTODISCOVER_1_FAILURE -1
151 #define SIPE_EWS_STATE_AUTODISCOVER_2_FAILURE -2
152 #define SIPE_EWS_STATE_AVAILABILITY_SUCCESS 3
153 #define SIPE_EWS_STATE_AVAILABILITY_FAILURE -3
154 #define SIPE_EWS_STATE_OOF_SUCCESS 4
155 #define SIPE_EWS_STATE_OOF_FAILURE -4
157 char *
158 sipe_ews_get_oof_note(struct sipe_calendar *cal)
160 time_t now = time(NULL);
162 if (!cal || !cal->oof_state) return NULL;
164 if (sipe_strequal(cal->oof_state, "Enabled") ||
165 (sipe_strequal(cal->oof_state, "Scheduled") && now >= cal->oof_start && now <= cal->oof_end))
167 return cal->oof_note;
169 else
171 return NULL;
175 static void
176 sipe_ews_run_state_machine(struct sipe_calendar *cal);
178 static void sipe_ews_process_avail_response(SIPE_UNUSED_PARAMETER struct sipe_core_private *sipe_private,
179 guint status,
180 SIPE_UNUSED_PARAMETER GSList *headers,
181 const gchar *body,
182 gpointer data)
184 struct sipe_calendar *cal = data;
186 SIPE_DEBUG_INFO_NOFORMAT("sipe_ews_process_avail_response: cb started.");
188 cal->request = NULL;
190 if ((status == SIPE_HTTP_STATUS_OK) && body) {
191 const sipe_xml *node;
192 const sipe_xml *resp;
193 /** ref: [MS-OXWAVLS] */
194 sipe_xml *xml = sipe_xml_parse(body, strlen(body));
196 Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/ResponseMessage@ResponseClass="Success"
197 Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/FreeBusyView/MergedFreeBusy
198 Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/FreeBusyView/CalendarEventArray/CalendarEvent
199 Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/FreeBusyView/WorkingHours
201 resp = sipe_xml_child(xml, "Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse");
202 if (!resp) return; /* rather soap:Fault */
203 if (!sipe_strequal(sipe_xml_attribute(sipe_xml_child(resp, "ResponseMessage"), "ResponseClass"), "Success")) {
204 return; /* Error response */
207 /* MergedFreeBusy */
208 g_free(cal->free_busy);
209 cal->free_busy = sipe_xml_data(sipe_xml_child(resp, "FreeBusyView/MergedFreeBusy"));
211 /* WorkingHours */
212 node = sipe_xml_child(resp, "FreeBusyView/WorkingHours");
213 g_free(cal->working_hours_xml_str);
214 cal->working_hours_xml_str = sipe_xml_stringify(node);
215 SIPE_DEBUG_INFO("sipe_ews_process_avail_response: cal->working_hours_xml_str:\n%s",
216 cal->working_hours_xml_str ? cal->working_hours_xml_str : "");
218 sipe_cal_events_free(cal->cal_events);
219 cal->cal_events = NULL;
220 /* CalendarEvents */
221 for (node = sipe_xml_child(resp, "FreeBusyView/CalendarEventArray/CalendarEvent");
222 node;
223 node = sipe_xml_twin(node))
225 char *tmp;
227 <CalendarEvent>
228 <StartTime>2009-12-07T13:30:00</StartTime>
229 <EndTime>2009-12-07T14:30:00</EndTime>
230 <BusyType>Busy</BusyType>
231 <CalendarEventDetails>
232 <ID>0000000...</ID>
233 <Subject>Lunch</Subject>
234 <Location>Cafe</Location>
235 <IsMeeting>false</IsMeeting>
236 <IsRecurring>true</IsRecurring>
237 <IsException>false</IsException>
238 <IsReminderSet>true</IsReminderSet>
239 <IsPrivate>false</IsPrivate>
240 </CalendarEventDetails>
241 </CalendarEvent>
243 struct sipe_cal_event *cal_event = g_new0(struct sipe_cal_event, 1);
244 cal->cal_events = g_slist_append(cal->cal_events, cal_event);
246 tmp = sipe_xml_data(sipe_xml_child(node, "StartTime"));
247 cal_event->start_time = sipe_utils_str_to_time(tmp);
248 g_free(tmp);
250 tmp = sipe_xml_data(sipe_xml_child(node, "EndTime"));
251 cal_event->end_time = sipe_utils_str_to_time(tmp);
252 g_free(tmp);
254 tmp = sipe_xml_data(sipe_xml_child(node, "BusyType"));
255 if (sipe_strequal("Free", tmp)) {
256 cal_event->cal_status = SIPE_CAL_FREE;
257 } else if (sipe_strequal("Tentative", tmp)) {
258 cal_event->cal_status = SIPE_CAL_TENTATIVE;
259 } else if (sipe_strequal("Busy", tmp)) {
260 cal_event->cal_status = SIPE_CAL_BUSY;
261 } else if (sipe_strequal("OOF", tmp)) {
262 cal_event->cal_status = SIPE_CAL_OOF;
263 } else {
264 cal_event->cal_status = SIPE_CAL_NO_DATA;
266 g_free(tmp);
268 cal_event->subject = sipe_xml_data(sipe_xml_child(node, "CalendarEventDetails/Subject"));
269 cal_event->location = sipe_xml_data(sipe_xml_child(node, "CalendarEventDetails/Location"));
271 tmp = sipe_xml_data(sipe_xml_child(node, "CalendarEventDetails/IsMeeting"));
272 cal_event->is_meeting = tmp ? sipe_strequal(tmp, "true") : TRUE;
273 g_free(tmp);
276 sipe_xml_free(xml);
278 cal->state = SIPE_EWS_STATE_AVAILABILITY_SUCCESS;
279 sipe_ews_run_state_machine(cal);
281 } else {
282 cal->state = SIPE_EWS_STATE_AVAILABILITY_FAILURE;
283 sipe_ews_run_state_machine(cal);
287 static void sipe_ews_process_oof_response(SIPE_UNUSED_PARAMETER struct sipe_core_private *sipe_private,
288 guint status,
289 SIPE_UNUSED_PARAMETER GSList *headers,
290 const gchar *body,
291 gpointer data)
293 struct sipe_calendar *cal = data;
295 SIPE_DEBUG_INFO_NOFORMAT("sipe_ews_process_oof_response: cb started.");
297 cal->request = NULL;
299 if ((status == SIPE_HTTP_STATUS_OK) && body) {
300 char *old_note;
301 const sipe_xml *resp;
302 const sipe_xml *xn_duration;
303 /** ref: [MS-OXWOOF] */
304 sipe_xml *xml = sipe_xml_parse(body, strlen(body));
305 /* Envelope/Body/GetUserOofSettingsResponse/ResponseMessage@ResponseClass="Success"
306 * Envelope/Body/GetUserOofSettingsResponse/OofSettings/OofState=Enabled
307 * Envelope/Body/GetUserOofSettingsResponse/OofSettings/Duration/StartTime
308 * Envelope/Body/GetUserOofSettingsResponse/OofSettings/Duration/EndTime
309 * Envelope/Body/GetUserOofSettingsResponse/OofSettings/InternalReply/Message
311 resp = sipe_xml_child(xml, "Body/GetUserOofSettingsResponse");
312 if (!resp) return; /* rather soap:Fault */
313 if (!sipe_strequal(sipe_xml_attribute(sipe_xml_child(resp, "ResponseMessage"), "ResponseClass"), "Success")) {
314 return; /* Error response */
317 g_free(cal->oof_state);
318 cal->oof_state = sipe_xml_data(sipe_xml_child(resp, "OofSettings/OofState"));
320 old_note = cal->oof_note;
321 cal->oof_note = NULL;
322 if (!sipe_strequal(cal->oof_state, "Disabled")) {
323 char *tmp = sipe_xml_data(
324 sipe_xml_child(resp, "OofSettings/InternalReply/Message"));
325 char *html;
327 /* UTF-8 encoded BOM (0xEF 0xBB 0xBF) as a signature to mark the beginning of a UTF-8 file */
328 if (g_str_has_prefix(tmp, "\xEF\xBB\xBF")) {
329 html = g_strdup(tmp+3);
330 } else {
331 html = g_strdup(tmp);
333 g_free(tmp);
334 tmp = g_strstrip(sipe_backend_markup_strip_html(html));
335 g_free(html);
336 cal->oof_note = g_markup_escape_text(tmp, -1);
337 g_free(tmp);
340 if (sipe_strequal(cal->oof_state, "Scheduled")
341 && (xn_duration = sipe_xml_child(resp, "OofSettings/Duration")))
343 char *tmp = sipe_xml_data(sipe_xml_child(xn_duration, "StartTime"));
344 cal->oof_start = sipe_utils_str_to_time(tmp);
345 g_free(tmp);
347 tmp = sipe_xml_data(sipe_xml_child(xn_duration, "EndTime"));
348 cal->oof_end = sipe_utils_str_to_time(tmp);
349 g_free(tmp);
352 if (!sipe_strequal(old_note, cal->oof_note)) { /* oof note changed */
353 cal->updated = time(NULL);
354 cal->published = FALSE;
356 g_free(old_note);
358 sipe_xml_free(xml);
360 cal->state = SIPE_EWS_STATE_OOF_SUCCESS;
361 sipe_ews_run_state_machine(cal);
363 } else {
364 cal->state = SIPE_EWS_STATE_OOF_FAILURE;
365 sipe_ews_run_state_machine(cal);
369 static void sipe_ews_process_autodiscover(SIPE_UNUSED_PARAMETER struct sipe_core_private *sipe_private,
370 guint status,
371 SIPE_UNUSED_PARAMETER GSList *headers,
372 const gchar *body,
373 gpointer data)
375 struct sipe_calendar *cal = data;
377 SIPE_DEBUG_INFO_NOFORMAT("sipe_ews_process_autodiscover: cb started.");
379 cal->request = NULL;
381 if ((status == SIPE_HTTP_STATUS_OK) && body) {
382 const sipe_xml *node;
383 /** ref: [MS-OXDSCLI] */
384 sipe_xml *xml = sipe_xml_parse(body, strlen(body));
386 /* Autodiscover/Response/User/LegacyDN (trim()) */
387 cal->legacy_dn = sipe_xml_data(sipe_xml_child(xml, "Response/User/LegacyDN"));
388 cal->legacy_dn = cal->legacy_dn ? g_strstrip(cal->legacy_dn) : NULL;
390 /* Protocols */
391 for (node = sipe_xml_child(xml, "Response/Account/Protocol");
392 node;
393 node = sipe_xml_twin(node))
395 char *type = sipe_xml_data(sipe_xml_child(node, "Type"));
396 if (sipe_strequal("EXCH", type)) {
397 cal->as_url = sipe_xml_data(sipe_xml_child(node, "ASUrl"));
398 cal->oof_url = sipe_xml_data(sipe_xml_child(node, "OOFUrl"));
399 cal->oab_url = sipe_xml_data(sipe_xml_child(node, "OABUrl"));
401 SIPE_DEBUG_INFO("sipe_ews_process_autodiscover:as_url %s",
402 cal->as_url ? cal->as_url : "");
403 SIPE_DEBUG_INFO("sipe_ews_process_autodiscover:oof_url %s",
404 cal->oof_url ? cal->oof_url : "");
405 SIPE_DEBUG_INFO("sipe_ews_process_autodiscover:oab_url %s",
406 cal->oab_url ? cal->oab_url : "");
408 g_free(type);
409 break;
410 } else {
411 g_free(type);
412 continue;
416 sipe_xml_free(xml);
418 cal->state = SIPE_EWS_STATE_AUTODISCOVER_SUCCESS;
419 sipe_ews_run_state_machine(cal);
421 } else if ((status == SIPE_HTTP_STATUS_CLIENT_FORBIDDEN) && cal->retry) {
423 * Authentication succeeded but we still weren't allowed to view the page.
424 * At least at our work place this error is temporary, i.e. the next access
425 * with the exact same authentication succeeds. Simply retry once.
427 SIPE_DEBUG_INFO_NOFORMAT("sipe_ews_process_autodiscover: failed, let's retry once.");
428 sipe_ews_run_state_machine(cal);
429 cal->retry = FALSE;
431 } else {
432 switch (cal->auto_disco_method) {
433 case 1:
434 cal->state = SIPE_EWS_STATE_AUTODISCOVER_1_FAILURE; break;
435 case 2:
436 cal->state = SIPE_EWS_STATE_AUTODISCOVER_2_FAILURE; break;
438 sipe_ews_run_state_machine(cal);
442 static void sipe_ews_send_http_request(struct sipe_calendar *cal)
444 sipe_cal_http_authentication(cal);
445 sipe_http_request_allow_redirect(cal->request);
446 sipe_http_request_ready(cal->request);
449 static void sipe_ews_do_autodiscover(struct sipe_calendar *cal,
450 const gchar *autodiscover_url)
452 gchar *body;
454 SIPE_DEBUG_INFO("sipe_ews_do_autodiscover: going autodiscover url=%s",
455 autodiscover_url ? autodiscover_url : "");
457 body = g_strdup_printf(SIPE_EWS_AUTODISCOVER_REQUEST, cal->email);
458 cal->request = sipe_http_request_post(cal->sipe_private,
459 autodiscover_url,
460 NULL,
461 body,
462 "text/xml",
463 sipe_ews_process_autodiscover,
464 cal);
465 g_free(body);
467 sipe_ews_send_http_request(cal);
470 static void sipe_ews_do_avail_request(struct sipe_calendar *cal)
472 if (cal->as_url) {
473 char *body;
474 time_t end;
475 time_t now = time(NULL);
476 char *start_str;
477 char *end_str;
478 struct tm *now_tm;
480 SIPE_DEBUG_INFO_NOFORMAT("sipe_ews_do_avail_request: going Availability req.");
482 now_tm = gmtime(&now);
483 /* start -1 day, 00:00:00 */
484 now_tm->tm_sec = 0;
485 now_tm->tm_min = 0;
486 now_tm->tm_hour = 0;
487 cal->fb_start = sipe_mktime_tz(now_tm, "UTC");
488 cal->fb_start -= 24*60*60;
489 /* end = start + 4 days - 1 sec */
490 end = cal->fb_start + SIPE_FREE_BUSY_PERIOD_SEC - 1;
492 start_str = sipe_utils_time_to_str(cal->fb_start);
493 end_str = sipe_utils_time_to_str(end);
495 body = g_strdup_printf(SIPE_EWS_USER_AVAILABILITY_REQUEST, cal->email, start_str, end_str);
496 cal->request = sipe_http_request_post(cal->sipe_private,
497 cal->as_url,
498 NULL,
499 body,
500 "text/xml; charset=UTF-8",
501 sipe_ews_process_avail_response,
502 cal);
503 g_free(body);
504 g_free(start_str);
505 g_free(end_str);
507 sipe_ews_send_http_request(cal);
511 static void sipe_ews_do_oof_request(struct sipe_calendar *cal)
513 if (cal->oof_url) {
514 char *body;
516 SIPE_DEBUG_INFO_NOFORMAT("sipe_ews_do_oof_request: going OOF req.");
518 body = g_strdup_printf(SIPE_EWS_USER_OOF_SETTINGS_REQUEST, cal->email);
519 cal->request = sipe_http_request_post(cal->sipe_private,
520 cal->as_url,
521 NULL,
522 body,
523 "text/xml; charset=UTF-8",
524 sipe_ews_process_oof_response,
525 cal);
526 g_free(body);
528 sipe_ews_send_http_request(cal);
532 static void
533 sipe_ews_run_state_machine(struct sipe_calendar *cal)
535 switch (cal->state) {
536 case SIPE_EWS_STATE_NONE:
538 char *maildomain = strstr(cal->email, "@") + 1;
539 char *autodisc_url = g_strdup_printf("https://Autodiscover.%s/Autodiscover/Autodiscover.xml", maildomain);
541 cal->retry = TRUE;
542 cal->auto_disco_method = 1;
544 sipe_ews_do_autodiscover(cal, autodisc_url);
546 g_free(autodisc_url);
547 break;
549 case SIPE_EWS_STATE_AUTODISCOVER_1_FAILURE:
551 char *maildomain = strstr(cal->email, "@") + 1;
552 char *autodisc_url = g_strdup_printf("https://%s/Autodiscover/Autodiscover.xml", maildomain);
554 cal->retry = TRUE;
555 cal->auto_disco_method = 2;
557 sipe_ews_do_autodiscover(cal, autodisc_url);
559 g_free(autodisc_url);
560 break;
562 case SIPE_EWS_STATE_AUTODISCOVER_2_FAILURE:
563 case SIPE_EWS_STATE_AVAILABILITY_FAILURE:
564 case SIPE_EWS_STATE_OOF_FAILURE:
565 cal->is_ews_disabled = TRUE;
566 break;
567 case SIPE_EWS_STATE_AUTODISCOVER_SUCCESS:
568 sipe_ews_do_avail_request(cal);
569 break;
570 case SIPE_EWS_STATE_AVAILABILITY_SUCCESS:
571 sipe_ews_do_oof_request(cal);
572 break;
573 case SIPE_EWS_STATE_OOF_SUCCESS:
575 struct sipe_core_private *sipe_private = cal->sipe_private;
577 cal->state = SIPE_EWS_STATE_AUTODISCOVER_SUCCESS;
578 cal->is_updated = TRUE;
579 sipe_cal_presence_publish(sipe_private, TRUE);
580 break;
585 void
586 sipe_ews_update_calendar(struct sipe_core_private *sipe_private)
588 //char *autodisc_srv = g_strdup_printf("_autodiscover._tcp.%s", maildomain);
589 gboolean has_url;
591 SIPE_DEBUG_INFO_NOFORMAT("sipe_ews_update_calendar: started.");
593 if (sipe_cal_calendar_init(sipe_private, &has_url)) {
594 if (has_url) {
595 sipe_private->calendar->state = SIPE_EWS_STATE_AUTODISCOVER_SUCCESS;
599 if (sipe_private->calendar->is_ews_disabled) {
600 SIPE_DEBUG_INFO_NOFORMAT("sipe_ews_update_calendar: disabled, exiting.");
601 return;
604 sipe_ews_run_state_machine(sipe_private->calendar);
606 SIPE_DEBUG_INFO_NOFORMAT("sipe_ews_update_calendar: finished.");
612 Local Variables:
613 mode: c
614 c-file-style: "bsd"
615 indent-tabs-mode: t
616 tab-width: 8
617 End: