presence.2005: choose note vs. oof note based on time
[siplcs.git] / src / core / sipe-ews.c
blobd3e19807e044a875fb09dd84070c50dfc3076634
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.
45 #include <string.h>
47 #include "debug.h"
48 #include "xmlnode.h"
50 #include "sipe.h"
51 /* for xmlnode_get_descendant */
52 #include "sipe-utils.h"
54 #include "sipe-ews.h"
55 #include "sipe-cal.h"
58 /**
59 * Autodiscover request for Exchange Web Services
60 * @param email (%s) Ex.: alice@cosmo.local
62 #define SIPE_EWS_AUTODISCOVER_REQUEST \
63 "<?xml version=\"1.0\"?>"\
64 "<Autodiscover xmlns=\"http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006\">"\
65 "<Request>"\
66 "<EMailAddress>%s</EMailAddress>"\
67 "<AcceptableResponseSchema>"\
68 "http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a"\
69 "</AcceptableResponseSchema>"\
70 "</Request>"\
71 "</Autodiscover>"
73 /**
74 * GetUserOofSettingsRequest SOAP request to Exchange Web Services
75 * to obtain our Out-of-office (OOF) information.
76 * @param email (%s) Ex.: alice@cosmo.local
78 #define SIPE_EWS_USER_OOF_SETTINGS_REQUEST \
79 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
80 "<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/\">"\
81 "<soap:Body>"\
82 "<GetUserOofSettingsRequest xmlns=\"http://schemas.microsoft.com/exchange/services/2006/messages\">"\
83 "<Mailbox xmlns=\"http://schemas.microsoft.com/exchange/services/2006/types\">"\
84 "<Address>%s</Address>"\
85 "</Mailbox>"\
86 "</GetUserOofSettingsRequest>"\
87 "</soap:Body>"\
88 "</soap:Envelope>"
90 /**
91 * GetUserAvailabilityRequest SOAP request to Exchange Web Services
92 * to obtain our Availability (FreeBusy, WorkingHours, Meetings) information.
93 * @param email (%s) Ex.: alice@cosmo.local
94 * @param start_time (%s) Ex.: 2009-12-06T00:00:00
95 * @param end_time (%s) Ex.: 2009-12-09T23:59:59
97 #define SIPE_EWS_USER_AVAILABILITY_REQUEST \
98 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
99 "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
100 " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
101 " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
102 " xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\">"\
103 "<soap:Body>"\
104 "<GetUserAvailabilityRequest xmlns=\"http://schemas.microsoft.com/exchange/services/2006/messages\""\
105 " xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\">"\
106 "<t:TimeZone xmlns=\"http://schemas.microsoft.com/exchange/services/2006/types\">"\
107 "<Bias>0</Bias>"\
108 "<StandardTime>"\
109 "<Bias>0</Bias>"\
110 "<Time>00:00:00</Time>"\
111 "<DayOrder>0</DayOrder>"\
112 "<Month>0</Month>"\
113 "<DayOfWeek>Sunday</DayOfWeek>"\
114 "</StandardTime>"\
115 "<DaylightTime>"\
116 "<Bias>0</Bias>"\
117 "<Time>00:00:00</Time>"\
118 "<DayOrder>0</DayOrder>"\
119 "<Month>0</Month>"\
120 "<DayOfWeek>Sunday</DayOfWeek>"\
121 "</DaylightTime>"\
122 "</t:TimeZone>"\
123 "<MailboxDataArray>"\
124 "<t:MailboxData>"\
125 "<t:Email>"\
126 "<t:Address>%s</t:Address>"\
127 "</t:Email>"\
128 "<t:AttendeeType>Required</t:AttendeeType>"\
129 "<t:ExcludeConflicts>false</t:ExcludeConflicts>"\
130 "</t:MailboxData>"\
131 "</MailboxDataArray>"\
132 "<t:FreeBusyViewOptions>"\
133 "<t:TimeWindow>"\
134 "<t:StartTime>%s</t:StartTime>"\
135 "<t:EndTime>%s</t:EndTime>"\
136 "</t:TimeWindow>"\
137 "<t:MergedFreeBusyIntervalInMinutes>15</t:MergedFreeBusyIntervalInMinutes>"\
138 "<t:RequestedView>DetailedMerged</t:RequestedView>"\
139 "</t:FreeBusyViewOptions>"\
140 "</GetUserAvailabilityRequest>"\
141 "</soap:Body>"\
142 "</soap:Envelope>"
144 #define SIPE_EWS_STATE_NONE 0
145 #define SIPE_EWS_STATE_AUTODISCOVER_SUCCESS 1
146 #define SIPE_EWS_STATE_AUTODISCOVER_1_FAILURE -1
147 #define SIPE_EWS_STATE_AUTODISCOVER_2_FAILURE -2
148 #define SIPE_EWS_STATE_AVAILABILITY_SUCCESS 2
149 #define SIPE_EWS_STATE_OOF_SUCCESS 3
152 static void
153 sipe_ews_cal_events_free(GSList *cal_events)
155 GSList *entry = cal_events;
157 if (!cal_events) return;
159 while (entry) {
160 struct sipe_cal_event *cal_event = entry->data;
161 sipe_cal_event_free(cal_event);
162 entry = entry->next;
165 g_slist_free(cal_events);
168 void
169 sipe_ews_free(struct sipe_ews* ews)
171 g_free(ews->email);
172 g_free(ews->legacy_dn);
173 if (ews->auth) {
174 g_free(ews->auth->domain);
175 g_free(ews->auth->user);
176 g_free(ews->auth->password);
178 g_free(ews->auth);
179 g_free(ews->as_url);
180 g_free(ews->oof_url);
181 g_free(ews->oab_url);
182 g_free(ews->oof_state);
183 g_free(ews->oof_note);
184 g_free(ews->free_busy);
185 g_free(ews->working_hours_xml_str);
187 sipe_ews_cal_events_free(ews->cal_events);
189 g_free(ews);
192 char *
193 sipe_ews_get_oof_note(struct sipe_ews *ews)
195 time_t now = time(NULL);
197 if (!ews) return NULL;
199 if (!strcmp(ews->oof_state, "Enabled") ||
200 (!strcmp(ews->oof_state, "Scheduled") && now >= ews->oof_start && now <= ews->oof_end))
202 return ews->oof_note;
204 else
206 return NULL;
210 static void
211 sipe_ews_run_state_machine(struct sipe_ews *ews);
213 static void
214 sipe_ews_process_avail_response(int return_code,
215 const char *body,
216 void *data)
218 struct sipe_ews *ews = data;
220 purple_debug_info("sipe", "sipe_ews_process_avail_response: cb started.\n");
222 if(ews->oof_url && strcmp(ews->as_url, ews->oof_url)) { /* whether reuse conn */
223 http_conn_set_close(ews->http_conn);
224 ews->http_conn = NULL;
227 if (return_code == 200 && body) {
228 xmlnode *node;
229 xmlnode *resp;
230 /** ref: [MS-OXWAVLS] */
231 xmlnode *xml = xmlnode_from_str(body, strlen(body));
233 Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/ResponseMessage@ResponseClass="Success"
234 Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/FreeBusyView/MergedFreeBusy
235 Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/FreeBusyView/CalendarEventArray/CalendarEvent
236 Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/FreeBusyView/WorkingHours
238 resp = xmlnode_get_descendant(xml, "Body", "GetUserAvailabilityResponse", "FreeBusyResponseArray", "FreeBusyResponse", NULL);
239 if (!resp) return; /* rather soap:Fault */
240 if (strcmp(xmlnode_get_attrib(xmlnode_get_child(resp, "ResponseMessage"), "ResponseClass"), "Success")) {
241 return; /* Error response */
244 /* MergedFreeBusy */
245 g_free(ews->free_busy);
246 ews->free_busy = xmlnode_get_data(xmlnode_get_descendant(resp, "FreeBusyView", "MergedFreeBusy", NULL));
248 /* WorkingHours */
249 node = xmlnode_get_descendant(resp, "FreeBusyView", "WorkingHours", NULL);
250 g_free(ews->working_hours_xml_str);
251 ews->working_hours_xml_str = xmlnode_to_str(node, NULL);
252 purple_debug_info("sipe", "sipe_ews_process_avail_response: ews->working_hours_xml_str:\n%s\n",
253 ews->working_hours_xml_str ? ews->working_hours_xml_str : "");
255 sipe_ews_cal_events_free(ews->cal_events);
256 ews->cal_events = NULL;
257 /* CalendarEvents */
258 for (node = xmlnode_get_descendant(resp, "FreeBusyView", "CalendarEventArray", "CalendarEvent", NULL);
259 node;
260 node = xmlnode_get_next_twin(node))
262 char *tmp;
264 <CalendarEvent>
265 <StartTime>2009-12-07T13:30:00</StartTime>
266 <EndTime>2009-12-07T14:30:00</EndTime>
267 <BusyType>Busy</BusyType>
268 <CalendarEventDetails>
269 <ID>0000000...</ID>
270 <Subject>Lunch</Subject>
271 <Location>Cafe</Location>
272 <IsMeeting>false</IsMeeting>
273 <IsRecurring>true</IsRecurring>
274 <IsException>false</IsException>
275 <IsReminderSet>true</IsReminderSet>
276 <IsPrivate>false</IsPrivate>
277 </CalendarEventDetails>
278 </CalendarEvent>
280 struct sipe_cal_event *cal_event = g_new0(struct sipe_cal_event, 1);
281 ews->cal_events = g_slist_append(ews->cal_events, cal_event);
283 tmp = xmlnode_get_data(xmlnode_get_child(node, "StartTime"));
284 cal_event->start_time = purple_str_to_time(tmp, FALSE, NULL, NULL, NULL);
285 g_free(tmp);
287 tmp = xmlnode_get_data(xmlnode_get_child(node, "EndTime"));
288 cal_event->end_time = purple_str_to_time(tmp, FALSE, NULL, NULL, NULL);
289 g_free(tmp);
291 tmp = xmlnode_get_data(xmlnode_get_child(node, "BusyType"));
292 if (!strcmp("Free", tmp)) {
293 cal_event->cal_status = SIPE_CAL_FREE;
294 } else if (!strcmp("Tentative", tmp)) {
295 cal_event->cal_status = SIPE_CAL_TENTATIVE;
296 } else if (!strcmp("Busy", tmp)) {
297 cal_event->cal_status = SIPE_CAL_BUSY;
298 } else if (!strcmp("OOF", tmp)) {
299 cal_event->cal_status = SIPE_CAL_OOF;
300 } else {
301 cal_event->cal_status = SIPE_CAL_NO_DATA;
303 g_free(tmp);
305 cal_event->subject = xmlnode_get_data(xmlnode_get_descendant(node, "CalendarEventDetails", "Subject", NULL));
306 cal_event->location = xmlnode_get_data(xmlnode_get_descendant(node, "CalendarEventDetails", "Location", NULL));
308 tmp = xmlnode_get_data(xmlnode_get_descendant(node, "CalendarEventDetails", "IsMeeting", NULL));
309 cal_event->is_meeting = tmp ? !strcmp(tmp, "true") : TRUE;
310 g_free(tmp);
313 xmlnode_free(xml);
315 ews->state = SIPE_EWS_STATE_AVAILABILITY_SUCCESS;
316 sipe_ews_run_state_machine(ews);
318 } else if (return_code < 0) {
319 ews->http_conn = NULL;
323 static void
324 sipe_ews_process_oof_response(int return_code,
325 const char *body,
326 void *data)
328 struct sipe_ews *ews = data;
330 purple_debug_info("sipe", "sipe_ews_process_oof_response: cb started.\n");
332 http_conn_set_close(ews->http_conn);
333 ews->http_conn = NULL;
335 if (return_code == 200 && body) {
336 char *old_note;
337 xmlnode *resp;
338 xmlnode *xn_duration;
339 /** ref: [MS-OXWOOF] */
340 xmlnode *xml = xmlnode_from_str(body, strlen(body));
341 /* Envelope/Body/GetUserOofSettingsResponse/ResponseMessage@ResponseClass="Success"
342 * Envelope/Body/GetUserOofSettingsResponse/OofSettings/OofState=Enabled
343 * Envelope/Body/GetUserOofSettingsResponse/OofSettings/Duration/StartTime
344 * Envelope/Body/GetUserOofSettingsResponse/OofSettings/Duration/EndTime
345 * Envelope/Body/GetUserOofSettingsResponse/OofSettings/InternalReply/Message
347 resp = xmlnode_get_descendant(xml, "Body", "GetUserOofSettingsResponse", NULL);
348 if (!resp) return; /* rather soap:Fault */
349 if (strcmp(xmlnode_get_attrib(xmlnode_get_child(resp, "ResponseMessage"), "ResponseClass"), "Success")) {
350 return; /* Error response */
353 g_free(ews->oof_state);
354 ews->oof_state = xmlnode_get_data(xmlnode_get_descendant(resp, "OofSettings", "OofState", NULL));
356 old_note = ews->oof_note;
357 ews->oof_note = NULL;
358 if (strcmp(ews->oof_state, "Disabled")) {
359 char *tmp = xmlnode_get_data(
360 xmlnode_get_descendant(resp, "OofSettings", "InternalReply", "Message", NULL));
361 char *html;
362 /* UTF-8 encoded BOM (0xEF 0xBB 0xBF) as a signature to mark the beginning of a UTF-8 file */
363 if (tmp && !strncmp(tmp, "\xEF\xBB\xBF", 3)) {
364 html = purple_unescape_html(tmp+3);
365 } else {
366 html = purple_unescape_html(tmp);
368 g_free(tmp);
369 ews->oof_note = g_strstrip(purple_markup_strip_html(html));
370 g_free(html);
373 if (!strcmp(ews->oof_state, "Scheduled")
374 && (xn_duration = xmlnode_get_descendant(resp, "OofSettings", "Duration", NULL)))
376 char *tmp = xmlnode_get_data(xmlnode_get_child(xn_duration, "StartTime"));
377 ews->oof_start = purple_str_to_time(tmp, FALSE, NULL, NULL, NULL);
378 g_free(tmp);
380 tmp = xmlnode_get_data(xmlnode_get_child(xn_duration, "EndTime"));
381 ews->oof_end = purple_str_to_time(tmp, FALSE, NULL, NULL, NULL);
382 g_free(tmp);
383 } else {
384 if (!(old_note && ews->oof_note && !strcmp(old_note, ews->oof_note))) { /* oof note changed */
385 ews->oof_start = time(NULL);
386 ews->oof_end = (time_t)-1;
389 g_free(old_note);
391 xmlnode_free(xml);
393 ews->state = SIPE_EWS_STATE_OOF_SUCCESS;
394 sipe_ews_run_state_machine(ews);
396 } else if (return_code < 0) {
397 ews->http_conn = NULL;
401 static void
402 sipe_ews_process_autodiscover(int return_code,
403 const char *body,
404 void *data)
406 struct sipe_ews *ews = data;
408 purple_debug_info("sipe", "sipe_ews_process_autodiscover: cb started.\n");
410 http_conn_set_close(ews->http_conn);
411 ews->http_conn = NULL;
413 if (return_code == 200 && body) {
414 xmlnode *node;
415 /** ref: [MS-OXDSCLI] */
416 xmlnode *xml = xmlnode_from_str(body, strlen(body));
418 /* Autodiscover/Response/User/LegacyDN (trim()) */
419 ews->legacy_dn = xmlnode_get_data(xmlnode_get_descendant(xml, "Response", "User", "LegacyDN", NULL));
420 ews->legacy_dn = ews->legacy_dn ? g_strstrip(ews->legacy_dn) : NULL;
422 /* Protocols */
423 for (node = xmlnode_get_descendant(xml, "Response", "Account", "Protocol", NULL);
424 node;
425 node = xmlnode_get_next_twin(node))
427 char *type = xmlnode_get_data(xmlnode_get_child(node, "Type"));
428 if (!strcmp("EXCH", type)) {
429 ews->as_url = xmlnode_get_data(xmlnode_get_child(node, "ASUrl"));
430 ews->oof_url = xmlnode_get_data(xmlnode_get_child(node, "OOFUrl"));
431 ews->oab_url = xmlnode_get_data(xmlnode_get_child(node, "OABUrl"));
433 purple_debug_info("sipe", "sipe_ews_process_autodiscover:as_url %s\n",
434 ews->as_url ? ews->as_url : "");
435 purple_debug_info("sipe", "sipe_ews_process_autodiscover:oof_url %s\n",
436 ews->oof_url ? ews->oof_url : "");
437 purple_debug_info("sipe", "sipe_ews_process_autodiscover:oab_url %s\n",
438 ews->oab_url ? ews->oab_url : "");
440 g_free(type);
441 break;
442 } else {
443 g_free(type);
444 continue;
448 xmlnode_free(xml);
450 ews->state = SIPE_EWS_STATE_AUTODISCOVER_SUCCESS;
451 sipe_ews_run_state_machine(ews);
453 } else {
454 if (return_code < 0) {
455 ews->http_conn = NULL;
457 switch (ews->auto_disco_method) {
458 case 1:
459 ews->state = SIPE_EWS_STATE_AUTODISCOVER_1_FAILURE; break;
460 case 2:
461 ews->state = SIPE_EWS_STATE_AUTODISCOVER_2_FAILURE; break;
463 sipe_ews_run_state_machine(ews);
467 static void
468 sipe_ews_do_autodiscover(struct sipe_ews *ews,
469 const char* autodiscover_url)
471 char *body;
473 purple_debug_info("sipe", "sipe_ews_do_autodiscover: going autodiscover url=%s\n", autodiscover_url ? autodiscover_url : "");
475 body = g_strdup_printf(SIPE_EWS_AUTODISCOVER_REQUEST, ews->email);
476 ews->http_conn = http_conn_create(
477 ews->account,
478 HTTP_CONN_SSL,
479 autodiscover_url,
480 body,
481 "text/xml",
482 ews->auth,
483 (HttpConnCallback)sipe_ews_process_autodiscover,
484 ews);
485 g_free(body);
488 static void
489 sipe_ews_do_avail_request(struct sipe_ews *ews)
491 if (ews->as_url) {
492 char *body;
493 time_t end;
494 time_t now = time(NULL);
495 char *start_str;
496 char *end_str;
497 struct tm *now_tm;
499 purple_debug_info("sipe", "sipe_ews_do_avail_request: going Availability req.\n");
501 now_tm = gmtime(&now);
502 /* start -1 day, 00:00:00 */
503 now_tm->tm_sec = 0;
504 now_tm->tm_min = 0;
505 now_tm->tm_hour = 0;
506 ews->fb_start = sipe_mktime_tz(now_tm, "UTC");
507 ews->fb_start -= 24*60*60;
508 /* end = start + 4 days - 1 sec */
509 end = ews->fb_start + 4*(24*60*60) - 1;
511 start_str = g_strdup(purple_utf8_strftime(SIPE_XML_DATE_PATTERN, gmtime(&ews->fb_start)));
512 end_str = g_strdup(purple_utf8_strftime(SIPE_XML_DATE_PATTERN, gmtime(&end)));
514 body = g_strdup_printf(SIPE_EWS_USER_AVAILABILITY_REQUEST, ews->email, start_str, end_str);
515 ews->http_conn = http_conn_create(
516 ews->account,
517 HTTP_CONN_SSL,
518 ews->as_url,
519 body,
520 "text/xml; charset=UTF-8",
521 ews->auth,
522 (HttpConnCallback)sipe_ews_process_avail_response,
523 ews);
524 g_free(body);
525 g_free(start_str);
526 g_free(end_str);
530 static void
531 sipe_ews_do_oof_request(struct sipe_ews *ews)
533 if (ews->oof_url) {
534 char *body;
535 const char *content_type = "text/xml; charset=UTF-8";
537 purple_debug_info("sipe", "sipe_ews_do_oof_request: going OOF req.\n");
539 body = g_strdup_printf(SIPE_EWS_USER_OOF_SETTINGS_REQUEST, ews->email);
540 if (!ews->http_conn) {
541 ews->http_conn = http_conn_create(ews->account,
542 HTTP_CONN_SSL,
543 ews->oof_url,
544 body,
545 content_type,
546 ews->auth,
547 (HttpConnCallback)sipe_ews_process_oof_response,
548 ews);
549 } else {
550 http_conn_post(ews->http_conn,
551 ews->oof_url,
552 body,
553 content_type,
554 (HttpConnCallback)sipe_ews_process_oof_response,
555 ews);
557 g_free(body);
561 static void
562 sipe_ews_run_state_machine(struct sipe_ews *ews)
564 switch (ews->state) {
565 case SIPE_EWS_STATE_NONE:
567 char *maildomain = strstr(ews->email, "@") + 1;
568 char *autodisc_url = g_strdup_printf("https://Autodiscover.%s/Autodiscover/Autodiscover.xml", maildomain);
570 ews->auto_disco_method = 1;
572 sipe_ews_do_autodiscover(ews, autodisc_url);
574 g_free(autodisc_url);
575 break;
577 case SIPE_EWS_STATE_AUTODISCOVER_1_FAILURE:
579 char *maildomain = strstr(ews->email, "@") + 1;
580 char *autodisc_url = g_strdup_printf("https://%s/Autodiscover/Autodiscover.xml", maildomain);
582 ews->auto_disco_method = 2;
584 sipe_ews_do_autodiscover(ews, autodisc_url);
586 g_free(autodisc_url);
587 break;
589 case SIPE_EWS_STATE_AUTODISCOVER_2_FAILURE:
590 ews->is_disabled = TRUE;
591 break;
592 case SIPE_EWS_STATE_AUTODISCOVER_SUCCESS:
593 sipe_ews_do_avail_request(ews);
594 break;
595 case SIPE_EWS_STATE_AVAILABILITY_SUCCESS:
596 sipe_ews_do_oof_request(ews);
597 break;
598 case SIPE_EWS_STATE_OOF_SUCCESS:
599 ews->state = SIPE_EWS_STATE_AUTODISCOVER_SUCCESS;
600 ews->is_updated = TRUE;
601 if (ews->sip->ocs2007) {
602 /* sipe.h */
603 publish_calendar_status_self(ews->sip);
604 } else {
605 /* sipe.h */
606 send_presence_soap(ews->sip, TRUE);
608 break;
612 void
613 sipe_ews_update_calendar(struct sipe_account_data *sip)
615 //char *autodisc_srv = g_strdup_printf("_autodiscover._tcp.%s", maildomain);
617 purple_debug_info("sipe", "sipe_ews_update_calendar: started.\n");
619 if (!sip->ews) {
620 const char *email_url;
621 const char *email_login;
622 const char *email_password;
623 char *email_auth_user = NULL;
624 char *email_auth_domain = NULL;
625 char *tmp = NULL;
626 sip->ews = g_new0(struct sipe_ews, 1);
627 sip->ews->sip = sip;
629 sip->ews->account = sip->account;
630 email_url = purple_account_get_string(sip->account, "email_url", NULL);
631 email_login = purple_account_get_string(sip->account, "email_login", NULL);
632 email_password = purple_account_get_string(sip->account, "email_password", NULL);
634 if (email_url) {
635 sip->ews->as_url = g_strdup(email_url);
636 sip->ews->oof_url = g_strdup(email_url);
637 sip->ews->state = SIPE_EWS_STATE_AUTODISCOVER_SUCCESS;
640 if (email_login && (tmp = strstr(email_login, "\\"))) {
641 email_auth_user = g_strdup(tmp + 1);
642 email_auth_domain = g_strndup(email_login, tmp - email_login);
643 } else {
644 email_auth_user = g_strdup(email_login);
647 sip->ews->email = g_strdup(sip->email);
649 sip->ews->auth = g_new0(HttpConnAuth, 1);
650 sip->ews->auth->domain = !is_empty(email_login) ? email_auth_domain : g_strdup(sip->authdomain);
651 sip->ews->auth->user = !is_empty(email_login) ? email_auth_user : g_strdup(sip->authuser);
652 sip->ews->auth->password = !is_empty(email_login) ? g_strdup(email_password) : g_strdup(sip->password);
653 sip->ews->auth->use_negotiate = purple_account_get_bool(sip->account, "krb5", FALSE);
656 if(sip->ews->is_disabled) {
657 purple_debug_info("sipe", "sipe_ews_update_calendar: disabled, exiting.\n");
658 return;
661 sipe_ews_run_state_machine(sip->ews);
663 purple_debug_info("sipe", "sipe_ews_update_calendar: finished.\n");
669 Local Variables:
670 mode: c
671 c-file-style: "bsd"
672 indent-tabs-mode: t
673 tab-width: 8
674 End: