interface cleanup: flatten interface dependencies
[siplcs.git] / src / core / sipe-ews.c
blob8ab5c9f1bc829bb729ed17be146ceb0a76d354fb
1 /**
2 * @file sipe-ews.c
4 * pidgin-sipe
6 * Copyright (C) 2010, 2009 pier11 <pier11@operamail.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /**
25 For communication with Exchange 2007/2010 Web Server/Web Services:
27 1) Autodiscover (HTTPS POST request). With redirect support. XML content.
28 1.1) DNS SRV record _autodiscover._tcp.<domain> may also be resolved.
29 2) Availability Web service (SOAP = HTTPS POST + XML) call.
30 3) Out of Office (OOF) Web Service (SOAP = HTTPS POST + XML) call.
31 4) Web server authentication required - NTLM and/or Negotiate (Kerberos).
33 Note: ews - EWS stands for Exchange Web Services.
35 It will be able to retrieve our Calendar information (FreeBusy, WorkingHours,
36 Meetings Subject and Location, Is_Meeting) as well as our Out of Office (OOF) note
37 from Exchange Web Services for subsequent publishing.
39 Ref. for more implementation details:
40 http://sourceforge.net/projects/sipe/forums/forum/688535/topic/3403462
42 Similar functionality for Lotus Notes/Domino, iCalendar/CalDAV/Google would
43 be great to implement too.
46 #include <string.h>
47 #include <time.h>
49 #include <glib.h>
51 #include "account.h"
52 #include "blist.h"
53 #include "circbuffer.h"
54 #include "connection.h"
55 #include "debug.h"
56 #include "dnsquery.h"
57 #include "dnssrv.h"
58 #include "network.h"
59 #include "plugin.h"
60 #include "sslconn.h"
61 #include "xmlnode.h"
63 #include "sip-sec.h"
64 #include "sipe-xml.h"
65 #include "sipe-utils.h"
66 #include "http-conn.h"
67 #include "sipe-cal.h"
68 #include "sipe-ews.h"
69 #include "sipe.h"
71 /**
72 * Autodiscover request for Exchange Web Services
73 * @param email (%s) Ex.: alice@cosmo.local
75 #define SIPE_EWS_AUTODISCOVER_REQUEST \
76 "<?xml version=\"1.0\"?>"\
77 "<Autodiscover xmlns=\"http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006\">"\
78 "<Request>"\
79 "<EMailAddress>%s</EMailAddress>"\
80 "<AcceptableResponseSchema>"\
81 "http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a"\
82 "</AcceptableResponseSchema>"\
83 "</Request>"\
84 "</Autodiscover>"
86 /**
87 * GetUserOofSettingsRequest SOAP request to Exchange Web Services
88 * to obtain our Out-of-office (OOF) information.
89 * @param email (%s) Ex.: alice@cosmo.local
91 #define SIPE_EWS_USER_OOF_SETTINGS_REQUEST \
92 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
93 "<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/\">"\
94 "<soap:Body>"\
95 "<GetUserOofSettingsRequest xmlns=\"http://schemas.microsoft.com/exchange/services/2006/messages\">"\
96 "<Mailbox xmlns=\"http://schemas.microsoft.com/exchange/services/2006/types\">"\
97 "<Address>%s</Address>"\
98 "</Mailbox>"\
99 "</GetUserOofSettingsRequest>"\
100 "</soap:Body>"\
101 "</soap:Envelope>"
104 * GetUserAvailabilityRequest SOAP request to Exchange Web Services
105 * to obtain our Availability (FreeBusy, WorkingHours, Meetings) information.
106 * @param email (%s) Ex.: alice@cosmo.local
107 * @param start_time (%s) Ex.: 2009-12-06T00:00:00
108 * @param end_time (%s) Ex.: 2009-12-09T23:59:59
110 #define SIPE_EWS_USER_AVAILABILITY_REQUEST \
111 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
112 "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
113 " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
114 " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
115 " xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\">"\
116 "<soap:Body>"\
117 "<GetUserAvailabilityRequest xmlns=\"http://schemas.microsoft.com/exchange/services/2006/messages\""\
118 " xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\">"\
119 "<t:TimeZone xmlns=\"http://schemas.microsoft.com/exchange/services/2006/types\">"\
120 "<Bias>0</Bias>"\
121 "<StandardTime>"\
122 "<Bias>0</Bias>"\
123 "<Time>00:00:00</Time>"\
124 "<DayOrder>0</DayOrder>"\
125 "<Month>0</Month>"\
126 "<DayOfWeek>Sunday</DayOfWeek>"\
127 "</StandardTime>"\
128 "<DaylightTime>"\
129 "<Bias>0</Bias>"\
130 "<Time>00:00:00</Time>"\
131 "<DayOrder>0</DayOrder>"\
132 "<Month>0</Month>"\
133 "<DayOfWeek>Sunday</DayOfWeek>"\
134 "</DaylightTime>"\
135 "</t:TimeZone>"\
136 "<MailboxDataArray>"\
137 "<t:MailboxData>"\
138 "<t:Email>"\
139 "<t:Address>%s</t:Address>"\
140 "</t:Email>"\
141 "<t:AttendeeType>Required</t:AttendeeType>"\
142 "<t:ExcludeConflicts>false</t:ExcludeConflicts>"\
143 "</t:MailboxData>"\
144 "</MailboxDataArray>"\
145 "<t:FreeBusyViewOptions>"\
146 "<t:TimeWindow>"\
147 "<t:StartTime>%s</t:StartTime>"\
148 "<t:EndTime>%s</t:EndTime>"\
149 "</t:TimeWindow>"\
150 "<t:MergedFreeBusyIntervalInMinutes>15</t:MergedFreeBusyIntervalInMinutes>"\
151 "<t:RequestedView>DetailedMerged</t:RequestedView>"\
152 "</t:FreeBusyViewOptions>"\
153 "</GetUserAvailabilityRequest>"\
154 "</soap:Body>"\
155 "</soap:Envelope>"
157 #define SIPE_EWS_STATE_NONE 0
158 #define SIPE_EWS_STATE_AUTODISCOVER_SUCCESS 1
159 #define SIPE_EWS_STATE_AUTODISCOVER_1_FAILURE -1
160 #define SIPE_EWS_STATE_AUTODISCOVER_2_FAILURE -2
161 #define SIPE_EWS_STATE_AVAILABILITY_SUCCESS 2
162 #define SIPE_EWS_STATE_OOF_SUCCESS 3
165 static void
166 sipe_ews_cal_events_free(GSList *cal_events)
168 GSList *entry = cal_events;
170 if (!cal_events) return;
172 while (entry) {
173 struct sipe_cal_event *cal_event = entry->data;
174 sipe_cal_event_free(cal_event);
175 entry = entry->next;
178 g_slist_free(cal_events);
181 void
182 sipe_ews_free(struct sipe_ews* ews)
184 g_free(ews->email);
185 g_free(ews->legacy_dn);
186 if (ews->auth) {
187 g_free(ews->auth->domain);
188 g_free(ews->auth->user);
189 g_free(ews->auth->password);
191 g_free(ews->auth);
192 g_free(ews->as_url);
193 g_free(ews->oof_url);
194 g_free(ews->oab_url);
195 g_free(ews->oof_state);
196 g_free(ews->oof_note);
197 g_free(ews->free_busy);
198 g_free(ews->working_hours_xml_str);
200 sipe_ews_cal_events_free(ews->cal_events);
202 g_free(ews);
205 char *
206 sipe_ews_get_oof_note(struct sipe_ews *ews)
208 time_t now = time(NULL);
210 if (!ews || !ews->oof_state) return NULL;
212 if (sipe_strequal(ews->oof_state, "Enabled") ||
213 (sipe_strequal(ews->oof_state, "Scheduled") && now >= ews->oof_start && now <= ews->oof_end))
215 return ews->oof_note;
217 else
219 return NULL;
223 static void
224 sipe_ews_run_state_machine(struct sipe_ews *ews);
226 static void
227 sipe_ews_process_avail_response(int return_code,
228 const char *body,
229 HttpConn *conn,
230 void *data)
232 struct sipe_ews *ews = data;
234 purple_debug_info("sipe", "sipe_ews_process_avail_response: cb started.\n");
236 if(!sipe_strequal(ews->as_url, ews->oof_url)) { /* whether reuse conn */
237 http_conn_set_close(conn);
238 ews->http_conn = NULL;
241 if (return_code == 200 && body) {
242 const sipe_xml *node;
243 const sipe_xml *resp;
244 /** ref: [MS-OXWAVLS] */
245 sipe_xml *xml = sipe_xml_parse(body, strlen(body));
247 Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/ResponseMessage@ResponseClass="Success"
248 Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/FreeBusyView/MergedFreeBusy
249 Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/FreeBusyView/CalendarEventArray/CalendarEvent
250 Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/FreeBusyView/WorkingHours
252 resp = sipe_xml_child(xml, "Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse");
253 if (!resp) return; /* rather soap:Fault */
254 if (!sipe_strequal(sipe_xml_attribute(sipe_xml_child(resp, "ResponseMessage"), "ResponseClass"), "Success")) {
255 return; /* Error response */
258 /* MergedFreeBusy */
259 g_free(ews->free_busy);
260 ews->free_busy = sipe_xml_data(sipe_xml_child(resp, "FreeBusyView/MergedFreeBusy"));
262 /* WorkingHours */
263 node = sipe_xml_child(resp, "FreeBusyView/WorkingHours");
264 g_free(ews->working_hours_xml_str);
265 ews->working_hours_xml_str = sipe_xml_stringify(node);
266 purple_debug_info("sipe", "sipe_ews_process_avail_response: ews->working_hours_xml_str:\n%s\n",
267 ews->working_hours_xml_str ? ews->working_hours_xml_str : "");
269 sipe_ews_cal_events_free(ews->cal_events);
270 ews->cal_events = NULL;
271 /* CalendarEvents */
272 for (node = sipe_xml_child(resp, "FreeBusyView/CalendarEventArray/CalendarEvent");
273 node;
274 node = sipe_xml_twin(node))
276 char *tmp;
278 <CalendarEvent>
279 <StartTime>2009-12-07T13:30:00</StartTime>
280 <EndTime>2009-12-07T14:30:00</EndTime>
281 <BusyType>Busy</BusyType>
282 <CalendarEventDetails>
283 <ID>0000000...</ID>
284 <Subject>Lunch</Subject>
285 <Location>Cafe</Location>
286 <IsMeeting>false</IsMeeting>
287 <IsRecurring>true</IsRecurring>
288 <IsException>false</IsException>
289 <IsReminderSet>true</IsReminderSet>
290 <IsPrivate>false</IsPrivate>
291 </CalendarEventDetails>
292 </CalendarEvent>
294 struct sipe_cal_event *cal_event = g_new0(struct sipe_cal_event, 1);
295 ews->cal_events = g_slist_append(ews->cal_events, cal_event);
297 tmp = sipe_xml_data(sipe_xml_child(node, "StartTime"));
298 cal_event->start_time = sipe_utils_str_to_time(tmp);
299 g_free(tmp);
301 tmp = sipe_xml_data(sipe_xml_child(node, "EndTime"));
302 cal_event->end_time = sipe_utils_str_to_time(tmp);
303 g_free(tmp);
305 tmp = sipe_xml_data(sipe_xml_child(node, "BusyType"));
306 if (sipe_strequal("Free", tmp)) {
307 cal_event->cal_status = SIPE_CAL_FREE;
308 } else if (sipe_strequal("Tentative", tmp)) {
309 cal_event->cal_status = SIPE_CAL_TENTATIVE;
310 } else if (sipe_strequal("Busy", tmp)) {
311 cal_event->cal_status = SIPE_CAL_BUSY;
312 } else if (sipe_strequal("OOF", tmp)) {
313 cal_event->cal_status = SIPE_CAL_OOF;
314 } else {
315 cal_event->cal_status = SIPE_CAL_NO_DATA;
317 g_free(tmp);
319 cal_event->subject = sipe_xml_data(sipe_xml_child(node, "CalendarEventDetails/Subject"));
320 cal_event->location = sipe_xml_data(sipe_xml_child(node, "CalendarEventDetails/Location"));
322 tmp = sipe_xml_data(sipe_xml_child(node, "CalendarEventDetails/IsMeeting"));
323 cal_event->is_meeting = tmp ? sipe_strequal(tmp, "true") : TRUE;
324 g_free(tmp);
327 sipe_xml_free(xml);
329 ews->state = SIPE_EWS_STATE_AVAILABILITY_SUCCESS;
330 sipe_ews_run_state_machine(ews);
332 } else if (return_code < 0) {
333 ews->http_conn = NULL;
337 static void
338 sipe_ews_process_oof_response(int return_code,
339 const char *body,
340 HttpConn *conn,
341 void *data)
343 struct sipe_ews *ews = data;
345 purple_debug_info("sipe", "sipe_ews_process_oof_response: cb started.\n");
347 http_conn_set_close(conn);
348 ews->http_conn = NULL;
350 if (return_code == 200 && body) {
351 char *old_note;
352 const sipe_xml *resp;
353 const sipe_xml *xn_duration;
354 /** ref: [MS-OXWOOF] */
355 sipe_xml *xml = sipe_xml_parse(body, strlen(body));
356 /* Envelope/Body/GetUserOofSettingsResponse/ResponseMessage@ResponseClass="Success"
357 * Envelope/Body/GetUserOofSettingsResponse/OofSettings/OofState=Enabled
358 * Envelope/Body/GetUserOofSettingsResponse/OofSettings/Duration/StartTime
359 * Envelope/Body/GetUserOofSettingsResponse/OofSettings/Duration/EndTime
360 * Envelope/Body/GetUserOofSettingsResponse/OofSettings/InternalReply/Message
362 resp = sipe_xml_child(xml, "Body/GetUserOofSettingsResponse");
363 if (!resp) return; /* rather soap:Fault */
364 if (!sipe_strequal(sipe_xml_attribute(sipe_xml_child(resp, "ResponseMessage"), "ResponseClass"), "Success")) {
365 return; /* Error response */
368 g_free(ews->oof_state);
369 ews->oof_state = sipe_xml_data(sipe_xml_child(resp, "OofSettings/OofState"));
371 old_note = ews->oof_note;
372 ews->oof_note = NULL;
373 if (!sipe_strequal(ews->oof_state, "Disabled")) {
374 char *tmp = sipe_xml_data(
375 sipe_xml_child(resp, "OofSettings/InternalReply/Message"));
376 char *html;
378 /* UTF-8 encoded BOM (0xEF 0xBB 0xBF) as a signature to mark the beginning of a UTF-8 file */
379 if (g_str_has_prefix(tmp, "\xEF\xBB\xBF")) {
380 html = g_strdup(tmp+3);
381 } else {
382 html = g_strdup(tmp);
384 g_free(tmp);
385 tmp = g_strstrip(purple_markup_strip_html(html));
386 g_free(html);
387 ews->oof_note = g_markup_escape_text(tmp, -1);
388 g_free(tmp);
391 if (sipe_strequal(ews->oof_state, "Scheduled")
392 && (xn_duration = sipe_xml_child(resp, "OofSettings/Duration")))
394 char *tmp = sipe_xml_data(sipe_xml_child(xn_duration, "StartTime"));
395 ews->oof_start = sipe_utils_str_to_time(tmp);
396 g_free(tmp);
398 tmp = sipe_xml_data(sipe_xml_child(xn_duration, "EndTime"));
399 ews->oof_end = sipe_utils_str_to_time(tmp);
400 g_free(tmp);
403 if (!sipe_strequal(old_note, ews->oof_note)) { /* oof note changed */
404 ews->updated = time(NULL);
405 ews->published = FALSE;
407 g_free(old_note);
409 sipe_xml_free(xml);
411 ews->state = SIPE_EWS_STATE_OOF_SUCCESS;
412 sipe_ews_run_state_machine(ews);
414 } else if (return_code < 0) {
415 ews->http_conn = NULL;
419 static void
420 sipe_ews_process_autodiscover(int return_code,
421 const char *body,
422 HttpConn *conn,
423 void *data)
425 struct sipe_ews *ews = data;
427 purple_debug_info("sipe", "sipe_ews_process_autodiscover: cb started.\n");
429 http_conn_set_close(conn);
430 ews->http_conn = NULL;
432 if (return_code == 200 && body) {
433 const sipe_xml *node;
434 /** ref: [MS-OXDSCLI] */
435 sipe_xml *xml = sipe_xml_parse(body, strlen(body));
437 /* Autodiscover/Response/User/LegacyDN (trim()) */
438 ews->legacy_dn = sipe_xml_data(sipe_xml_child(xml, "Response/User/LegacyDN"));
439 ews->legacy_dn = ews->legacy_dn ? g_strstrip(ews->legacy_dn) : NULL;
441 /* Protocols */
442 for (node = sipe_xml_child(xml, "Response/Account/Protocol");
443 node;
444 node = sipe_xml_twin(node))
446 char *type = sipe_xml_data(sipe_xml_child(node, "Type"));
447 if (sipe_strequal("EXCH", type)) {
448 ews->as_url = sipe_xml_data(sipe_xml_child(node, "ASUrl"));
449 ews->oof_url = sipe_xml_data(sipe_xml_child(node, "OOFUrl"));
450 ews->oab_url = sipe_xml_data(sipe_xml_child(node, "OABUrl"));
452 purple_debug_info("sipe", "sipe_ews_process_autodiscover:as_url %s\n",
453 ews->as_url ? ews->as_url : "");
454 purple_debug_info("sipe", "sipe_ews_process_autodiscover:oof_url %s\n",
455 ews->oof_url ? ews->oof_url : "");
456 purple_debug_info("sipe", "sipe_ews_process_autodiscover:oab_url %s\n",
457 ews->oab_url ? ews->oab_url : "");
459 g_free(type);
460 break;
461 } else {
462 g_free(type);
463 continue;
467 sipe_xml_free(xml);
469 ews->state = SIPE_EWS_STATE_AUTODISCOVER_SUCCESS;
470 sipe_ews_run_state_machine(ews);
472 } else {
473 if (return_code < 0) {
474 ews->http_conn = NULL;
476 switch (ews->auto_disco_method) {
477 case 1:
478 ews->state = SIPE_EWS_STATE_AUTODISCOVER_1_FAILURE; break;
479 case 2:
480 ews->state = SIPE_EWS_STATE_AUTODISCOVER_2_FAILURE; break;
482 sipe_ews_run_state_machine(ews);
486 static void
487 sipe_ews_do_autodiscover(struct sipe_ews *ews,
488 const char* autodiscover_url)
490 char *body;
492 purple_debug_info("sipe", "sipe_ews_do_autodiscover: going autodiscover url=%s\n", autodiscover_url ? autodiscover_url : "");
494 body = g_strdup_printf(SIPE_EWS_AUTODISCOVER_REQUEST, ews->email);
495 ews->http_conn = http_conn_create(
496 ews->account,
497 HTTP_CONN_SSL,
498 autodiscover_url,
499 body,
500 "text/xml",
501 ews->auth,
502 sipe_ews_process_autodiscover,
503 ews);
504 g_free(body);
507 static void
508 sipe_ews_do_avail_request(struct sipe_ews *ews)
510 if (ews->as_url) {
511 char *body;
512 time_t end;
513 time_t now = time(NULL);
514 char *start_str;
515 char *end_str;
516 struct tm *now_tm;
518 purple_debug_info("sipe", "sipe_ews_do_avail_request: going Availability req.\n");
520 now_tm = gmtime(&now);
521 /* start -1 day, 00:00:00 */
522 now_tm->tm_sec = 0;
523 now_tm->tm_min = 0;
524 now_tm->tm_hour = 0;
525 ews->fb_start = sipe_mktime_tz(now_tm, "UTC");
526 ews->fb_start -= 24*60*60;
527 /* end = start + 4 days - 1 sec */
528 end = ews->fb_start + 4*(24*60*60) - 1;
530 start_str = sipe_utils_time_to_str(ews->fb_start);
531 end_str = sipe_utils_time_to_str(end);
533 body = g_strdup_printf(SIPE_EWS_USER_AVAILABILITY_REQUEST, ews->email, start_str, end_str);
534 ews->http_conn = http_conn_create(
535 ews->account,
536 HTTP_CONN_SSL,
537 ews->as_url,
538 body,
539 "text/xml; charset=UTF-8",
540 ews->auth,
541 sipe_ews_process_avail_response,
542 ews);
543 g_free(body);
544 g_free(start_str);
545 g_free(end_str);
549 static void
550 sipe_ews_do_oof_request(struct sipe_ews *ews)
552 if (ews->oof_url) {
553 char *body;
554 const char *content_type = "text/xml; charset=UTF-8";
556 purple_debug_info("sipe", "sipe_ews_do_oof_request: going OOF req.\n");
558 body = g_strdup_printf(SIPE_EWS_USER_OOF_SETTINGS_REQUEST, ews->email);
559 if (!ews->http_conn) {
560 ews->http_conn = http_conn_create(ews->account,
561 HTTP_CONN_SSL,
562 ews->oof_url,
563 body,
564 content_type,
565 ews->auth,
566 sipe_ews_process_oof_response,
567 ews);
568 } else {
569 http_conn_post(ews->http_conn,
570 ews->oof_url,
571 body,
572 content_type,
573 sipe_ews_process_oof_response,
574 ews);
576 g_free(body);
580 static void
581 sipe_ews_run_state_machine(struct sipe_ews *ews)
583 switch (ews->state) {
584 case SIPE_EWS_STATE_NONE:
586 char *maildomain = strstr(ews->email, "@") + 1;
587 char *autodisc_url = g_strdup_printf("https://Autodiscover.%s/Autodiscover/Autodiscover.xml", maildomain);
589 ews->auto_disco_method = 1;
591 sipe_ews_do_autodiscover(ews, autodisc_url);
593 g_free(autodisc_url);
594 break;
596 case SIPE_EWS_STATE_AUTODISCOVER_1_FAILURE:
598 char *maildomain = strstr(ews->email, "@") + 1;
599 char *autodisc_url = g_strdup_printf("https://%s/Autodiscover/Autodiscover.xml", maildomain);
601 ews->auto_disco_method = 2;
603 sipe_ews_do_autodiscover(ews, autodisc_url);
605 g_free(autodisc_url);
606 break;
608 case SIPE_EWS_STATE_AUTODISCOVER_2_FAILURE:
609 ews->is_disabled = TRUE;
610 break;
611 case SIPE_EWS_STATE_AUTODISCOVER_SUCCESS:
612 sipe_ews_do_avail_request(ews);
613 break;
614 case SIPE_EWS_STATE_AVAILABILITY_SUCCESS:
615 sipe_ews_do_oof_request(ews);
616 break;
617 case SIPE_EWS_STATE_OOF_SUCCESS:
618 ews->state = SIPE_EWS_STATE_AUTODISCOVER_SUCCESS;
619 ews->is_updated = TRUE;
620 if (ews->sip->ocs2007) {
621 /* sipe.h */
622 publish_calendar_status_self(ews->sip);
623 } else {
624 /* sipe.h */
625 send_presence_soap(ews->sip, TRUE);
627 break;
631 void
632 sipe_ews_update_calendar(struct sipe_account_data *sip)
634 //char *autodisc_srv = g_strdup_printf("_autodiscover._tcp.%s", maildomain);
636 purple_debug_info("sipe", "sipe_ews_update_calendar: started.\n");
638 if (!sip->ews) {
639 const char *value;
641 sip->ews = g_new0(struct sipe_ews, 1);
642 sip->ews->sip = sip;
644 sip->ews->account = sip->account;
645 sip->ews->email = g_strdup(sip->email);
647 /* user specified a service URL? */
648 value = purple_account_get_string(sip->account, "email_url", NULL);
649 if (!is_empty(value)) {
650 sip->ews->as_url = g_strdup(value);
651 sip->ews->oof_url = g_strdup(value);
652 sip->ews->state = SIPE_EWS_STATE_AUTODISCOVER_SUCCESS;
655 sip->ews->auth = g_new0(HttpConnAuth, 1);
656 sip->ews->auth->use_negotiate = purple_account_get_bool(sip->account, "krb5", FALSE);
658 /* user specified email login? */
659 value = purple_account_get_string(sip->account, "email_login", NULL);
660 if (!is_empty(value)) {
662 /* user specified email login domain? */
663 const char *tmp = strstr(value, "\\");
664 if (tmp) {
665 sip->ews->auth->domain = g_strndup(value, tmp - value);
666 sip->ews->auth->user = g_strdup(tmp + 1);
667 } else {
668 sip->ews->auth->user = g_strdup(value);
670 sip->ews->auth->password = g_strdup(purple_account_get_string(sip->account, "email_password", NULL));
672 } else {
673 /* re-use SIPE credentials */
674 sip->ews->auth->domain = g_strdup(sip->authdomain);
675 sip->ews->auth->user = g_strdup(sip->authuser);
676 sip->ews->auth->password = g_strdup(sip->password);
680 if(sip->ews->is_disabled) {
681 purple_debug_info("sipe", "sipe_ews_update_calendar: disabled, exiting.\n");
682 return;
685 sipe_ews_run_state_machine(sip->ews);
687 purple_debug_info("sipe", "sipe_ews_update_calendar: finished.\n");
693 Local Variables:
694 mode: c
695 c-file-style: "bsd"
696 indent-tabs-mode: t
697 tab-width: 8
698 End: