2
Convert Exchange appointments and meetings to ICAL files
6
Copyright (C) Julien Kerihuel 2008
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program. If not, see <http://www.gnu.org/licenses/>.
22
#include "libexchange2ical/libexchange2ical.h"
30
static const struct RRULE_byday RRULE_byday[] = {
41
static const char *get_filename(const char *filename)
45
if (!filename) return NULL;
47
substr = rindex(filename, '/');
48
if (substr) return substr;
54
void ical_property_ATTACH(struct exchange2ical *exchange2ical)
56
mapi_object_t obj_tb_attach;
57
mapi_object_t obj_attach;
58
mapi_object_t obj_stream;
59
struct SRowSet rowset_attach;
60
struct SPropTagArray *SPropTagArray = NULL;
61
const uint32_t *attach_num = NULL;
62
struct SPropValue *lpProps;
63
enum MAPISTATUS retval;
69
mapi_object_init(&obj_tb_attach);
70
retval = GetAttachmentTable(&exchange2ical->obj_message, &obj_tb_attach);
71
if (retval == MAPI_E_SUCCESS) {
72
SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x1, PR_ATTACH_NUM);
73
retval = SetColumns(&obj_tb_attach, SPropTagArray);
74
MAPIFreeBuffer(SPropTagArray);
75
retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rowset_attach);
77
for (i = 0; i < rowset_attach.cRows; i++) {
78
attach_num = (const uint32_t *)find_SPropValue_data(&(rowset_attach.aRow[i]), PR_ATTACH_NUM);
79
retval = OpenAttach(&exchange2ical->obj_message, *attach_num, &obj_attach);
81
if (retval == MAPI_E_SUCCESS) {
83
SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x7,
85
PR_ATTACH_LONG_FILENAME,
93
lpProps = talloc_zero(exchange2ical->mem_ctx, struct SPropValue);
94
retval = GetProps(&obj_attach, SPropTagArray, &lpProps, &count);
95
MAPIFreeBuffer(SPropTagArray);
96
if (retval == MAPI_E_SUCCESS) {
98
uint32_t *attachmentFlags = NULL;
99
uint32_t *attachMethod = NULL;
100
uint8_t *attachmentHidden = NULL;
101
const char *data = NULL;
102
const char *fmttype = NULL;
103
const char *attach_filename = NULL;
105
icalattach *icalattach = NULL;
106
icalproperty *prop = NULL;
107
icalparameter *param = NULL;
110
aRow2.ulAdrEntryPad = 0;
111
aRow2.cValues = count;
112
aRow2.lpProps = lpProps;
114
attachmentFlags = octool_get_propval(&aRow2, PR_ATTACHMENT_FLAGS);
115
attachMethod = octool_get_propval(&aRow2, PR_ATTACH_METHOD);
116
attachmentHidden = octool_get_propval(&aRow2, PR_ATTACHMENT_HIDDEN);
118
if(!(*attachmentFlags & 0x00000007)
119
&& (*attachMethod == 0x00000001)
120
&& (!attachmentHidden || !(*attachmentHidden))) {
122
/* Get data of attachment */
123
retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream);
124
retval = octool_get_stream(exchange2ical->mem_ctx, &obj_stream, &body);
125
data=ldb_base64_encode(exchange2ical->mem_ctx, (const char *)body.data, body.length);
127
/*Create a new icalattach from above data*/
128
icalattach = icalattach_new_from_data((unsigned char *)data,0,0);
130
/*Add attach property to vevent component*/
131
prop = icalproperty_new_attach(icalattach);
132
icalcomponent_add_property(exchange2ical->vevent, prop);
134
/* Attachment filename for X-FILENAME parameter*/
135
attach_filename = get_filename(octool_get_propval(&aRow2, PR_ATTACH_LONG_FILENAME));
136
if (!attach_filename || (attach_filename && !strcmp(attach_filename, ""))) {
137
attach_filename = get_filename(octool_get_propval(&aRow2, PR_ATTACH_FILENAME));
140
/* fmttype parameter */
141
fmttype = (const char *) octool_get_propval(&aRow2, PR_ATTACH_MIME_TAG);
143
param = icalparameter_new_fmttype(fmttype);
144
icalproperty_add_parameter(prop, param);
147
/* ENCODING parameter */
148
param =icalparameter_new_encoding(ICAL_ENCODING_BASE64);
149
icalproperty_add_parameter(prop,param);
151
/* VALUE parameter */
152
param=icalparameter_new_value(ICAL_VALUE_BINARY);
153
icalproperty_add_parameter(prop,param);
155
/* X-FILENAME parameter */
156
param = icalparameter_new_x(attach_filename);
157
icalparameter_set_xname(param,"X-FILENAME");
158
icalproperty_add_parameter(prop,param);
160
MAPIFreeBuffer(lpProps);
165
mapi_object_release(&obj_tb_attach);
169
// TODO: check this - need an example
170
void ical_property_ATTENDEE(struct exchange2ical *exchange2ical)
174
const char *display_name;
175
uint32_t *RecipientFlags;
176
uint32_t *RecipientType;
177
uint32_t *TrackStatus;
178
struct SRowSet *SRowSet;
181
if (!exchange2ical->apptStateFlags) return;
182
if (!(*exchange2ical->apptStateFlags & 0x1)) return;
183
SRowSet = &(exchange2ical->Recipients.SRowSet);
185
/* Loop over the recipient table */
186
for (i = 0; i < SRowSet->cRows; i++) {
187
smtp = (const char *) octool_get_propval(&(SRowSet->aRow[i]), PR_SMTP_ADDRESS);
188
display_name = (const char *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_DISPLAY_NAME);
189
RecipientFlags = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_FLAGS);
190
RecipientType = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_TYPE);
191
TrackStatus = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_TRACKSTATUS);
194
if (RecipientFlags && !(*RecipientFlags & 0x20) && !(*RecipientFlags & 0x2) &&
195
(RecipientType && *RecipientType)) {
198
icalparameter *participantType;
199
enum icalparameter_partstat partstat = ICAL_PARTSTAT_NONE;
203
mailtoURL = talloc_strdup(exchange2ical->mem_ctx, "mailto:");
204
mailtoURL = talloc_strdup_append(mailtoURL, smtp);
205
prop = icalproperty_new_attendee(mailtoURL);
206
icalcomponent_add_property(exchange2ical->vevent, prop);
208
prop = icalproperty_new_attendee("invalid:nomail");
209
icalcomponent_add_property(exchange2ical->vevent, prop);
213
cn = icalparameter_new_cn(display_name);
214
icalproperty_add_parameter(prop, cn);
217
if (*RecipientType == 0x3) {
218
icalparameter *cutype = icalparameter_new_cutype(ICAL_CUTYPE_RESOURCE);
219
icalproperty_add_parameter(prop, cutype);
222
switch (*RecipientType) {
224
participantType = icalparameter_new_role(ICAL_ROLE_OPTPARTICIPANT);
225
icalproperty_add_parameter(prop, participantType);
228
participantType = icalparameter_new_role(ICAL_ROLE_NONPARTICIPANT);
229
icalproperty_add_parameter(prop, participantType);
235
if((exchange2ical->method==ICAL_METHOD_REPLY) || (exchange2ical->method==ICAL_METHOD_COUNTER)){
236
partstat = exchange2ical->partstat;
237
}else if(exchange2ical->method==ICAL_METHOD_PUBLISH){
239
partstat = get_ical_partstat_from_status(*TrackStatus);
240
}else if(exchange2ical->ResponseStatus){
241
partstat = get_ical_partstat_from_status(*exchange2ical->ResponseStatus);
245
if (partstat != ICAL_PARTSTAT_NONE) {
246
icalparameter *param;
247
param = icalparameter_new_partstat(partstat);
248
icalproperty_add_parameter(prop, param);
251
if (exchange2ical->ResponseRequested) {
253
if (*(exchange2ical->ResponseRequested)) {
254
rsvp = icalparameter_new_rsvp(ICAL_RSVP_TRUE);
256
rsvp = icalparameter_new_rsvp(ICAL_RSVP_FALSE);
258
icalproperty_add_parameter(prop, rsvp);
265
void ical_property_CATEGORIES(struct exchange2ical *exchange2ical)
271
if (!exchange2ical->Keywords) return;
272
if (!exchange2ical->Keywords->cValues) return;
274
for (i = 0; i < exchange2ical->Keywords->cValues; i++) {
275
prop = icalproperty_new_categories(exchange2ical->Keywords->lppszA[i]);
276
icalcomponent_add_property(exchange2ical->vevent, prop);
282
void ical_property_CLASS(struct exchange2ical *exchange2ical)
287
if (!exchange2ical->sensitivity) return;
289
prop = icalproperty_new_class(get_ical_class(*exchange2ical->sensitivity));
290
icalcomponent_add_property(exchange2ical->vevent, prop);
294
void ical_property_CONTACT(struct exchange2ical *exchange2ical)
300
if (!exchange2ical->Contacts) return;
301
if (!exchange2ical->Contacts->cValues) return;
303
for (i = 0; i < exchange2ical->Contacts->cValues; i++) {
304
prop = icalproperty_new_contact(exchange2ical->Contacts->lppszA[i]);
305
icalcomponent_add_property(exchange2ical->vevent, prop);
310
void ical_property_CREATED(struct exchange2ical *exchange2ical)
313
struct icaltimetype icaltime;
316
if (!exchange2ical->created) return;
318
icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->created);
320
prop = icalproperty_new_created(icaltime);
321
icalcomponent_add_property(exchange2ical->vevent, prop);
324
void ical_property_DTSTART(struct exchange2ical *exchange2ical)
328
struct icaltimetype icaltime;
331
if (!exchange2ical->apptStartWhole) return;
333
/* If this is an all-day appointment */
334
if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
335
icaltime = get_icaldate_from_FILETIME(exchange2ical->apptStartWhole);
336
prop = icalproperty_new_dtstart(icaltime);
337
icalcomponent_add_property(exchange2ical->vevent, prop);
339
if (exchange2ical->TimeZoneDesc) {
340
icaltime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole);
341
prop = icalproperty_new_dtstart(icaltime);
342
icalcomponent_add_property(exchange2ical->vevent, prop);
343
tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
344
icalproperty_add_parameter(prop, tzid);
346
icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptStartWhole);
347
prop = icalproperty_new_dtstart(icaltime);
348
icalcomponent_add_property(exchange2ical->vevent, prop);
356
void ical_property_DTEND(struct exchange2ical *exchange2ical)
360
struct icaltimetype icaltime;
363
if (!exchange2ical->apptEndWhole) return;
365
/* If this is an all-day appointment */
366
if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
367
icaltime = get_icaldate_from_FILETIME(exchange2ical->apptEndWhole);
368
prop = icalproperty_new_dtend(icaltime);
369
icalcomponent_add_property(exchange2ical->vevent, prop);
371
if (exchange2ical->TimeZoneDesc) {
372
icaltime = get_icaltime_from_FILETIME(exchange2ical->apptEndWhole);
373
prop = icalproperty_new_dtend(icaltime);
374
icalcomponent_add_property(exchange2ical->vevent, prop);
375
tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
376
icalproperty_add_parameter(prop, tzid);
378
icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptEndWhole);
379
prop = icalproperty_new_dtend(icaltime);
380
icalcomponent_add_property(exchange2ical->vevent, prop);
387
void ical_property_DTSTAMP(struct exchange2ical *exchange2ical)
390
struct icaltimetype icaltime;
396
/*If OwnerCriticalChange field is null, get time system time*/
397
if (!exchange2ical->OwnerCriticalChange) {
400
icaltime = get_icaltimetype_from_tm_UTC(tm);
401
prop = icalproperty_new_dtstamp(icaltime);
402
icalcomponent_add_property(exchange2ical->vevent, prop);
405
icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->OwnerCriticalChange);
406
prop = icalproperty_new_dtstamp(icaltime);
407
icalcomponent_add_property(exchange2ical->vevent, prop);
408
if (exchange2ical->TimeZoneDesc) {
409
tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
410
icalproperty_add_parameter(prop, tzid);
416
void ical_property_DESCRIPTION(struct exchange2ical *exchange2ical)
420
if (exchange2ical->method == ICAL_METHOD_REPLY) return;
421
if (!exchange2ical->body) return;
423
prop = icalproperty_new_description(exchange2ical->body);
424
icalcomponent_add_property(exchange2ical->vevent, prop);
428
void ical_property_EXDATE(struct exchange2ical *exchange2ical)
433
struct icaltimetype icaltime;
434
struct icaltimetype dttime;
437
struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
440
if (exchange2ical->Recurring && (*exchange2ical->Recurring == 0x0)) return;
442
if (!pat->DeletedInstanceCount) return;
444
for (i = 0; i < pat->DeletedInstanceCount; i++) {
446
if(pat->ModifiedInstanceDates && pat->ModifiedInstanceCount){
447
for(j=0; j < pat->ModifiedInstanceCount; j++){
448
if(pat->ModifiedInstanceDates[j]==pat->DeletedInstanceDates[i]){
454
/* If this is an all-day appointment */
455
if (!modified && exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
457
tm = get_tm_from_minutes_UTC(pat->DeletedInstanceDates[i]);
458
icaltime= get_icaldate_from_tm(&tm);
459
prop = icalproperty_new_exdate(icaltime);
460
icalcomponent_add_property(exchange2ical->vevent, prop);
461
} else if (!modified){
462
/* number of minutes between midnight of the specified
463
* day and midnight, January 1, 1601 */
465
tm = get_tm_from_minutes_UTC(pat->DeletedInstanceDates[i]);
466
icaltime= get_icaltimetype_from_tm(&tm);
468
if (exchange2ical->TimeZoneDesc) {
469
/*Get time from dtstart*/
470
if (exchange2ical->apptEndWhole){
471
dttime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole);
472
icaltime.hour = dttime.hour;
473
icaltime.minute = dttime.minute;
476
prop = icalproperty_new_exdate(icaltime);
477
icalcomponent_add_property(exchange2ical->vevent, prop);
478
icalparameter *tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
479
icalproperty_add_parameter(prop, tzid);
481
/*Get time from dtstart*/
483
if (exchange2ical->apptEndWhole){
484
dttime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptStartWhole);
485
icaltime.hour = dttime.hour;
486
icaltime.minute = dttime.minute;
488
prop = icalproperty_new_exdate(icaltime);
489
icalcomponent_add_property(exchange2ical->vevent, prop);
497
void ical_property_LAST_MODIFIED(struct exchange2ical *exchange2ical)
500
struct icaltimetype icaltime;
505
if (!exchange2ical->LastModified) return;
506
if (exchange2ical->TimeZoneDesc) {
507
icaltime=get_icaltime_from_FILETIME(exchange2ical->LastModified);
508
prop = icalproperty_new_lastmodified(icaltime);
509
tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
510
icalproperty_add_parameter(prop, tzid);
512
icaltime=get_icaltime_from_FILETIME_UTC(exchange2ical->LastModified);
513
prop = icalproperty_new_lastmodified(icaltime);
515
icalcomponent_add_property(exchange2ical->vevent, prop);
519
void ical_property_LOCATION(struct exchange2ical *exchange2ical)
523
if (!exchange2ical->Location) return;
525
prop = icalproperty_new_location(exchange2ical->Location);
526
icalcomponent_add_property(exchange2ical->vevent, prop);
530
void ical_property_ORGANIZER(struct exchange2ical *exchange2ical)
533
const char *display_name;
534
uint32_t *RecipientFlags;
535
uint32_t *RecipientType;
537
struct SRowSet *SRowSet;
540
if (!exchange2ical->apptStateFlags) return;
541
if (!(*exchange2ical->apptStateFlags & 0x1)) return;
543
SRowSet = &(exchange2ical->Recipients.SRowSet);
545
/* Loop over the recipient table */
546
for (i = 0; i < SRowSet->cRows; i++) {
547
smtp = (const char *) octool_get_propval(&(SRowSet->aRow[i]), PR_SMTP_ADDRESS);
548
display_name = (const char *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_DISPLAY_NAME);
549
RecipientFlags = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_FLAGS);
550
RecipientType = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_TYPE);
552
if (RecipientFlags && !(*RecipientFlags & 0x20) &&
553
((*RecipientFlags & 0x2) || (RecipientType && !*RecipientType))) {
559
mailtoURL = talloc_strdup(exchange2ical->mem_ctx, "mailto:");
560
mailtoURL = talloc_strdup_append(mailtoURL, smtp);
561
prop = icalproperty_new_organizer(mailtoURL);
562
icalcomponent_add_property(exchange2ical->vevent, prop);
563
talloc_free(mailtoURL);
565
prop = icalproperty_new_organizer("invalid:nomail");
566
icalcomponent_add_property(exchange2ical->vevent, prop);
570
cn = icalparameter_new_cn(display_name);
571
icalproperty_add_parameter(prop, cn);
578
void ical_property_PRIORITY(struct exchange2ical *exchange2ical)
582
if (!exchange2ical->Importance) return;
584
switch (*exchange2ical->Importance) {
586
prop = icalproperty_new_priority(9);
589
prop = icalproperty_new_priority(5);
592
prop = icalproperty_new_priority(1);
595
prop = icalproperty_new_priority(5);
597
icalcomponent_add_property(exchange2ical->vevent, prop);
601
void ical_property_RRULE_Daily(struct exchange2ical *exchange2ical)
603
struct icalrecurrencetype recurrence;
605
struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
608
icalrecurrencetype_clear(&recurrence);
609
recurrence.freq = ICAL_DAILY_RECURRENCE;
610
recurrence.interval = (pat->Period / 1440);
612
if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
613
recurrence.count = pat->OccurrenceCount;
615
prop = icalproperty_new_rrule(recurrence);
616
icalcomponent_add_property(exchange2ical->vevent, prop);
620
void ical_property_RRULE_Weekly(struct exchange2ical *exchange2ical)
622
struct icalrecurrencetype recurrence;
624
struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
625
uint32_t rdfDaysBitmask = pat->PatternTypeSpecific.WeekRecurrencePattern;
628
icalrecurrencetype_clear(&recurrence);
629
recurrence.freq = ICAL_WEEKLY_RECURRENCE;
630
recurrence.interval = pat->Period;
633
switch(pat->FirstDOW){
634
case FirstDOW_Sunday:
635
recurrence.week_start=ICAL_SUNDAY_WEEKDAY;
637
case FirstDOW_Monday:
638
recurrence.week_start=ICAL_MONDAY_WEEKDAY;
640
case FirstDOW_Tuesday:
641
recurrence.week_start=ICAL_TUESDAY_WEEKDAY;
643
case FirstDOW_Wednesday:
644
recurrence.week_start=ICAL_WEDNESDAY_WEEKDAY;
646
case FirstDOW_Thursday:
647
recurrence.week_start=ICAL_THURSDAY_WEEKDAY;
649
case FirstDOW_Friday:
650
recurrence.week_start=ICAL_FRIDAY_WEEKDAY;
652
case FirstDOW_Saturday:
653
recurrence.week_start=ICAL_SATURDAY_WEEKDAY;
658
if (rdfDaysBitmask & Su) {
659
recurrence.by_day[idx] = ICAL_SUNDAY_WEEKDAY;
662
if (rdfDaysBitmask & M) {
663
recurrence.by_day[idx] = ICAL_MONDAY_WEEKDAY;
666
if (rdfDaysBitmask & Tu) {
667
recurrence.by_day[idx] = ICAL_TUESDAY_WEEKDAY;
670
if (rdfDaysBitmask & W) {
671
recurrence.by_day[idx] = ICAL_WEDNESDAY_WEEKDAY;
674
if (rdfDaysBitmask & Th) {
675
recurrence.by_day[idx] = ICAL_THURSDAY_WEEKDAY;
678
if (rdfDaysBitmask & F) {
679
recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
682
if (rdfDaysBitmask & Sa) {
683
recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
686
recurrence.by_day[idx] = ICAL_RECURRENCE_ARRAY_MAX;
688
if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
689
recurrence.count = pat->OccurrenceCount;
692
prop = icalproperty_new_rrule(recurrence);
693
icalcomponent_add_property(exchange2ical->vevent, prop);
697
void ical_property_RRULE_Monthly(struct exchange2ical *exchange2ical)
699
struct icalrecurrencetype recurrence;
701
struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
702
uint32_t day = pat->PatternTypeSpecific.Day;
704
icalrecurrencetype_clear(&recurrence);
705
recurrence.freq = ICAL_MONTHLY_RECURRENCE;
706
recurrence.interval = pat->Period;
708
if (day == 0x0000001F) {
709
recurrence.by_month_day[0] = -1;
711
recurrence.by_month_day[0] = day;
713
recurrence.by_month_day[1] = ICAL_RECURRENCE_ARRAY_MAX;
715
if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
716
recurrence.count = pat->OccurrenceCount;
719
prop = icalproperty_new_rrule(recurrence);
720
icalcomponent_add_property(exchange2ical->vevent, prop);
724
void ical_property_RRULE_NthMonthly(struct exchange2ical *exchange2ical)
726
struct icalrecurrencetype recurrence;
728
struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
729
uint32_t rdfDaysBitmask = pat->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern;
731
enum RecurrenceN setpos = pat->PatternTypeSpecific.MonthRecurrencePattern.N;
733
icalrecurrencetype_clear(&recurrence);
734
recurrence.freq = ICAL_MONTHLY_RECURRENCE;
735
recurrence.interval = pat->Period;
737
if (rdfDaysBitmask & Su) {
738
recurrence.by_day[idx] = ICAL_SUNDAY_WEEKDAY;
741
if (rdfDaysBitmask & M) {
742
recurrence.by_day[idx] = ICAL_MONDAY_WEEKDAY;
745
if (rdfDaysBitmask & Tu) {
746
recurrence.by_day[idx] = ICAL_TUESDAY_WEEKDAY;
749
if (rdfDaysBitmask & W) {
750
recurrence.by_day[idx] = ICAL_WEDNESDAY_WEEKDAY;
753
if (rdfDaysBitmask & Th) {
754
recurrence.by_day[idx] = ICAL_THURSDAY_WEEKDAY;
757
if (rdfDaysBitmask & F) {
758
recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
761
if (rdfDaysBitmask & Sa) {
762
recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
765
recurrence.by_day[idx] = ICAL_RECURRENCE_ARRAY_MAX;
767
if (setpos == RecurrenceN_First) {
768
recurrence.by_set_pos[0] = 1;
769
recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
770
} else if (setpos == RecurrenceN_Second) {
771
recurrence.by_set_pos[0] = 2;
772
recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
773
} else if (setpos == RecurrenceN_Third) {
774
recurrence.by_set_pos[0] = 3;
775
recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
776
} else if (setpos == RecurrenceN_Fourth) {
777
recurrence.by_set_pos[0] = 4;
778
recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
779
} else if (setpos == RecurrenceN_Last) {
780
recurrence.by_set_pos[0] = -1;
781
recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
784
if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
785
recurrence.count = pat->OccurrenceCount;
788
prop = icalproperty_new_rrule(recurrence);
789
icalcomponent_add_property(exchange2ical->vevent, prop);
793
void ical_property_RRULE_Yearly(struct exchange2ical *exchange2ical)
795
struct icalrecurrencetype recurrence;
797
struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
798
uint32_t day = pat->PatternTypeSpecific.Day;
799
struct icaltimetype icaltime;
801
icalrecurrencetype_clear(&recurrence);
802
recurrence.freq = ICAL_YEARLY_RECURRENCE;
803
recurrence.interval = (pat->Period / 12);
805
if (day == 0x0000001F) {
806
recurrence.by_month_day[0] = -1;
808
recurrence.by_month_day[0] = day;
810
recurrence.by_month_day[1] = ICAL_RECURRENCE_ARRAY_MAX;
812
icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptStartWhole);
813
recurrence.by_month[0] = icaltime.month;
814
recurrence.by_month[1] = ICAL_RECURRENCE_ARRAY_MAX;
818
if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
819
recurrence.count = pat->OccurrenceCount;
822
prop = icalproperty_new_rrule(recurrence);
823
icalcomponent_add_property(exchange2ical->vevent, prop);
826
void ical_property_RRULE_NthYearly(struct exchange2ical *exchange2ical)
828
struct icalrecurrencetype recurrence;
830
struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
831
uint32_t rdfDaysBitmask = pat->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern;
833
enum RecurrenceN setpos = pat->PatternTypeSpecific.MonthRecurrencePattern.N;
835
struct icaltimetype icaltime;
837
icalrecurrencetype_clear(&recurrence);
838
recurrence.freq = ICAL_YEARLY_RECURRENCE;
839
recurrence.interval = (pat->Period / 12);
841
if (rdfDaysBitmask & Su) {
842
recurrence.by_day[idx] = ICAL_SUNDAY_WEEKDAY;
845
if (rdfDaysBitmask & M) {
846
recurrence.by_day[idx] = ICAL_MONDAY_WEEKDAY;
849
if (rdfDaysBitmask & Tu) {
850
recurrence.by_day[idx] = ICAL_TUESDAY_WEEKDAY;
853
if (rdfDaysBitmask & W) {
854
recurrence.by_day[idx] = ICAL_WEDNESDAY_WEEKDAY;
857
if (rdfDaysBitmask & Th) {
858
recurrence.by_day[idx] = ICAL_THURSDAY_WEEKDAY;
861
if (rdfDaysBitmask & F) {
862
recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
865
if (rdfDaysBitmask & Sa) {
866
recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
869
recurrence.by_day[idx] = ICAL_RECURRENCE_ARRAY_MAX;
871
if (setpos == RecurrenceN_First) {
872
recurrence.by_set_pos[0] = 1;
873
recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
874
} else if (setpos == RecurrenceN_Second) {
875
recurrence.by_set_pos[0] = 2;
876
recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
877
} else if (setpos == RecurrenceN_Third) {
878
recurrence.by_set_pos[0] = 3;
879
recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
880
} else if (setpos == RecurrenceN_Fourth) {
881
recurrence.by_set_pos[0] = 4;
882
recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
883
} else if (setpos == RecurrenceN_Last) {
884
recurrence.by_set_pos[0] = -1;
885
recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
888
icaltime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole);
889
recurrence.by_month[0] = icaltime.month;
890
recurrence.by_month[1] = ICAL_RECURRENCE_ARRAY_MAX;
892
if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
893
recurrence.count = pat->OccurrenceCount;
896
prop = icalproperty_new_rrule(recurrence);
897
icalcomponent_add_property(exchange2ical->vevent, prop);
901
void ical_property_RRULE(struct exchange2ical *exchange2ical)
903
struct RecurrencePattern *pat;
906
if (!(exchange2ical->RecurrencePattern)) return;
908
pat = exchange2ical->RecurrencePattern;
910
switch(pat->PatternType) {
911
case PatternType_Day:
912
ical_property_RRULE_Daily(exchange2ical);
914
case PatternType_Week:
915
ical_property_RRULE_Weekly(exchange2ical);
917
case PatternType_Month:
918
if ((pat->Period % 12 ) == 0) {
919
ical_property_RRULE_Yearly(exchange2ical);
921
ical_property_RRULE_Monthly(exchange2ical);
924
case PatternType_MonthNth:
925
if ((pat->Period % 12 ) == 0) {
926
ical_property_RRULE_NthYearly(exchange2ical);
928
ical_property_RRULE_NthMonthly(exchange2ical);
932
printf("RRULE pattern type not implemented yet!:0x%x\n", pat->PatternType);
936
void ical_property_RRULE_daylight_standard(icalcomponent* component , struct SYSTEMTIME st)
938
struct icalrecurrencetype recurrence;
941
icalrecurrencetype_clear(&recurrence);
942
recurrence.freq = ICAL_YEARLY_RECURRENCE;
944
if(st.wYear ==0x0000){
945
recurrence.by_month[0]=st.wMonth;
946
/* Microsoft day of week = libIcal day of week +1; */
947
/* Day encode = day + occurrence*8 */
949
/* Last occurrence of day in the month*/
950
recurrence.by_day[0] = -1 * (st.wDayOfWeek + 9);
952
/* st.wDay occurrence of day in the month */
953
recurrence.by_day[0] = (st.wDayOfWeek + 1 + st.wDay*8);
957
recurrence.by_month_day[0]=st.wDay;
958
recurrence.by_month[0]=st.wMonth;
962
prop = icalproperty_new_rrule(recurrence);
963
icalcomponent_add_property(component, prop);
967
void ical_property_RECURRENCE_ID(struct exchange2ical *exchange2ical)
969
struct icaltimetype icaltime;
972
struct GlobalObjectId *GlbObjId;
975
if (exchange2ical->ExceptionReplaceTime){
976
/*if parent has an all day event*/
977
if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
978
icaltime = get_icaldate_from_FILETIME(exchange2ical->ExceptionReplaceTime);
979
prop = icalproperty_new_recurrenceid(icaltime);
980
icalcomponent_add_property(exchange2ical->vevent, prop);
982
if (exchange2ical->TimeZoneDesc) {
983
icaltime=get_icaltime_from_FILETIME(exchange2ical->ExceptionReplaceTime);
984
prop = icalproperty_new_recurrenceid(icaltime);
985
icalcomponent_add_property(exchange2ical->vevent, prop);
986
tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
987
icalproperty_add_parameter(prop, tzid);
989
icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->ExceptionReplaceTime);
990
prop = icalproperty_new_recurrenceid(icaltime);
991
icalcomponent_add_property(exchange2ical->vevent, prop);
994
} else if (exchange2ical->GlobalObjectId){
995
GlbObjId = get_GlobalObjectId(exchange2ical->mem_ctx, exchange2ical->GlobalObjectId);
997
icaltime=get_icaldate_from_GlobalObjectId(GlbObjId);
998
prop = icalproperty_new_recurrenceid(icaltime);
999
icalcomponent_add_property(exchange2ical->vevent, prop);
1000
talloc_free(GlbObjId);
1008
void ical_property_RESOURCES(struct exchange2ical *exchange2ical)
1010
char *NonSendableBcc = NULL;
1014
if (!exchange2ical->NonSendableBcc) return;
1016
NonSendableBcc = talloc_strdup(exchange2ical->mem_ctx, exchange2ical->NonSendableBcc);
1017
all_string_sub(NonSendableBcc, ";", ",", 0);
1018
prop = icalproperty_new_resources(NonSendableBcc);
1019
icalcomponent_add_property(exchange2ical->vevent, prop);
1020
talloc_free(NonSendableBcc);
1024
void ical_property_SEQUENCE(struct exchange2ical *exchange2ical)
1027
if (!exchange2ical->Sequence) {
1028
prop = icalproperty_new_sequence(0);
1030
prop = icalproperty_new_sequence(*(exchange2ical->Sequence));
1032
icalcomponent_add_property(exchange2ical->vevent, prop);
1036
void ical_property_SUMMARY(struct exchange2ical *exchange2ical)
1039
icalparameter *language;
1041
if (exchange2ical->Subject) {
1042
prop = icalproperty_new_summary(exchange2ical->Subject);
1044
prop = icalproperty_new_summary("");
1047
if (exchange2ical->MessageLocaleId) {
1048
const char *langtag = mapi_get_locale_from_lcid( *(exchange2ical->MessageLocaleId) );
1049
language = icalparameter_new_language( langtag );
1050
icalproperty_add_parameter(prop, language);
1053
icalcomponent_add_property(exchange2ical->vevent, prop);
1057
void ical_property_TRANSP(struct exchange2ical *exchange2ical)
1062
if (!exchange2ical->BusyStatus) return;
1064
switch (*exchange2ical->BusyStatus) {
1066
prop = icalproperty_new_transp(ICAL_TRANSP_TRANSPARENT);
1071
prop = icalproperty_new_transp(ICAL_TRANSP_OPAQUE);
1074
prop = icalproperty_new_transp(ICAL_TRANSP_NONE);
1076
icalcomponent_add_property(exchange2ical->vevent, prop);
1080
void ical_property_TRIGGER(struct exchange2ical *exchange2ical)
1082
struct icaltriggertype duration;
1084
if (!exchange2ical->ReminderDelta) return;
1085
if (*exchange2ical->ReminderDelta == 0x5AE980E1) {
1086
duration = icaltriggertype_from_int(-15 * 60);
1087
prop = icalproperty_new_trigger(duration);
1088
icalcomponent_add_property(exchange2ical->valarm, prop);
1090
duration = icaltriggertype_from_int(*(exchange2ical->ReminderDelta) * -1 * 60);
1091
prop = icalproperty_new_trigger(duration);
1092
icalcomponent_add_property(exchange2ical->valarm, prop);
1097
#define GLOBAL_OBJECT_ID_DATA_START "\x76\x43\x61\x6c\x2d\x55\x69\x64\x01\x00\x00\x00"
1099
void ical_property_UID(struct exchange2ical *exchange2ical)
1104
struct GlobalObjectId *GlbObjId;
1107
outstr = talloc_strdup(exchange2ical->mem_ctx, "uid");
1109
if(exchange2ical->GlobalObjectId){
1110
GlbObjId = get_GlobalObjectId(exchange2ical->mem_ctx, exchange2ical->GlobalObjectId);
1114
if (exchange2ical->GlobalObjectId && GlbObjId) {
1115
if (GlbObjId->Size >= 12 && (0 == memcmp(GlbObjId->Data, GLOBAL_OBJECT_ID_DATA_START, 12))) {
1117
// TODO: could this code overrun GlobalObjectId->lpb?
1118
// TODO: I think we should start at 12, not at zero...
1119
for (i = 12; i < 52; i++) {
1121
snprintf(objID, 6, "%.2X", exchange2ical->GlobalObjectId->lpb[i]);
1122
outstr = talloc_strdup_append(outstr, objID);
1125
uid = (const char *)&(GlbObjId->Data[13]);
1126
outstr = talloc_strdup_append(outstr, uid);
1129
for (i = 0; i < 16; i++) {
1131
snprintf(objID, 6, "%.2X", exchange2ical->GlobalObjectId->lpb[i]);
1132
outstr = talloc_strdup_append(outstr, objID);
1134
/* YH, YL, Month and D must be set to 0 */
1135
outstr = talloc_strdup_append(outstr, "00000000");
1137
for (i = 20; i < exchange2ical->GlobalObjectId->cb; i++) {
1139
snprintf(objID, 6, "%.2X", exchange2ical->GlobalObjectId->lpb[i]);
1140
outstr = talloc_strdup_append(outstr, objID);
1143
talloc_free(GlbObjId);
1146
snprintf(objID, 32, "%i", exchange2ical->idx);
1147
outstr = talloc_strdup(outstr, objID);
1150
prop = icalproperty_new_uid(outstr);
1151
icalcomponent_add_property(exchange2ical->vevent, prop);
1152
talloc_free(outstr);
1156
static icalproperty * ical_property_add_x_property_value(icalcomponent *parent, const char* propname, const char* value)
1159
icalvalue *icalText;
1162
if (!parent) return NULL;
1163
if (!propname) return NULL;
1164
if (!value) return NULL;
1166
icalText = icalvalue_new_text(value);
1167
prop = icalproperty_new_x(icalvalue_as_ical_string(icalText));
1168
icalvalue_free(icalText);
1169
icalproperty_set_x_name(prop, propname);
1170
icalcomponent_add_property(parent, prop);
1174
void ical_property_X_ALT_DESC(struct exchange2ical *exchange2ical)
1177
icalparameter *param;
1180
if(!exchange2ical->bodyHTML) return;
1181
prop = ical_property_add_x_property_value(exchange2ical->vevent, "X-ALT-DESC",exchange2ical->bodyHTML);
1182
param = icalparameter_new_fmttype("text/html");
1183
icalproperty_add_parameter(prop, param);
1186
void ical_property_X_MICROSOFT_CDO_ATTENDEE_CRITICAL_CHANGE(struct exchange2ical *exchange2ical)
1192
if (!exchange2ical->AttendeeCriticalChange) return;
1194
tm = get_tm_from_FILETIME(exchange2ical->AttendeeCriticalChange);
1195
strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm);
1196
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-ATTENDEE-CRITICAL-CHANGE", outstr);
1200
void ical_property_X_MICROSOFT_CDO_BUSYSTATUS(struct exchange2ical *exchange2ical)
1203
if(!exchange2ical->BusyStatus) return;
1205
switch (*exchange2ical->BusyStatus) {
1207
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "FREE");
1210
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "TENTATIVE");
1213
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "BUSY");
1216
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "OOF");
1220
void ical_property_X_MICROSOFT_MSNCALENDAR_IMPORTANCE(struct exchange2ical *exchange2ical)
1223
if (!exchange2ical->Importance) return;
1225
switch (*exchange2ical->Importance) {
1227
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-MSNCALENDAR-IMPORTANCE", "0");
1230
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-MSNCALENDAR-IMPORTANCE", "1");
1233
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-MSNCALENDAR-IMPORTANCE", "2");
1238
void ical_property_X_MICROSOFT_CDO_INTENDEDSTATUS(struct exchange2ical *exchange2ical)
1240
if (!exchange2ical->IntendedBusyStatus) return;
1242
switch (*exchange2ical->IntendedBusyStatus) {
1244
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "FREE");
1247
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "TENTATIVE");
1250
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "BUSY");
1253
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "OOF");
1259
void ical_property_X_MICROSOFT_CDO_OWNERAPPTID(struct exchange2ical *exchange2ical)
1263
if (!exchange2ical->OwnerApptId) return;
1264
snprintf(outstr, 200, "%d", *(exchange2ical->OwnerApptId));
1265
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-OWNERAPPTID", outstr);
1269
void ical_property_X_MICROSOFT_CDO_OWNER_CRITICAL_CHANGE(struct exchange2ical *exchange2ical)
1275
if (!exchange2ical->OwnerCriticalChange) return;
1278
tm = get_tm_from_FILETIME(exchange2ical->OwnerCriticalChange);
1281
strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm);
1282
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-OWNER-CRITICAL-CHANGE", outstr);
1286
void ical_property_X_MICROSOFT_CDO_REPLYTIME(struct exchange2ical *exchange2ical)
1292
if (!exchange2ical->apptReplyTime) return;
1294
tm = get_tm_from_FILETIME(exchange2ical->apptReplyTime);
1295
strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm);
1296
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-REPLYTIME", outstr);
1300
void ical_property_X_MICROSOFT_DISALLOW_COUNTER(struct exchange2ical *exchange2ical)
1303
if (!exchange2ical->NotAllowPropose) return;
1305
if (*(exchange2ical->NotAllowPropose) == true) {
1306
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-DISALLOW-COUNTER", "TRUE");
1308
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-DISALLOW-COUNTER", "FALSE");
1313
void ical_property_X_MS_OLK_ALLOWEXTERNCHECK(struct exchange2ical *exchange2ical)
1316
if (!exchange2ical->AllowExternCheck) return;
1318
if (*(exchange2ical->AllowExternCheck) == true) {
1319
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-ALLOWEXTERNCHECK", "TRUE");
1321
ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-ALLOWEXTERNCHECK", "FALSE");
1326
void ical_property_X_MS_OLK_APPTLASTSEQUENCE(struct exchange2ical *exchange2ical)
1330
if (!exchange2ical->apptLastSequence) return;
1332
snprintf(outstr, 20, "%d", *exchange2ical->apptLastSequence);
1333
ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-APPTLASTSEQUENCE", outstr);
1337
void ical_property_X_MS_OLK_APPTSEQTIME(struct exchange2ical *exchange2ical)
1339
struct tm *tm = NULL;
1343
if (!exchange2ical->apptSeqTime) return;
1345
tm = get_tm_from_FILETIME(exchange2ical->apptSeqTime);
1346
strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm);
1347
ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-APPTSEQTIME", outstr);
1351
void ical_property_X_MS_OLK_AUTOFILLLOCATION(struct exchange2ical *exchange2ical)
1354
if (!exchange2ical->AutoFillLocation) return;
1356
if (*(exchange2ical->AutoFillLocation) == true) {
1357
ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOFILLLOCATION", "TRUE");
1359
ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOFILLLOCATION", "FALSE");
1364
void ical_property_X_MS_OLK_AUTOSTARTCHECK(struct exchange2ical *exchange2ical)
1367
if (!exchange2ical->AutoStartCheck) return;
1368
if (*(exchange2ical->AutoStartCheck) == true) {
1369
ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOSTARTCHECK", "TRUE");
1371
ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOSTARTCHECK", "FALSE");
1376
void ical_property_X_MS_OLK_COLLABORATEDOC(struct exchange2ical *exchange2ical)
1379
if (!exchange2ical->CollaborateDoc) return;
1380
if(!(*exchange2ical->CollaborateDoc)) return;
1382
ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-COLLABORATEDOC", exchange2ical->CollaborateDoc);
1386
void ical_property_X_MS_OLK_CONFCHECK(struct exchange2ical *exchange2ical)
1389
if (!exchange2ical->ConfCheck) return;
1391
ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-CONFCHECK", (*exchange2ical->ConfCheck == true) ? "TRUE" : "FALSE");
1395
void ical_property_X_MS_OLK_CONFTYPE(struct exchange2ical *exchange2ical)
1399
if (!exchange2ical->ConfType) return;
1401
snprintf(outstr, 20, "%d", *exchange2ical->ConfType);
1402
ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-CONFTYPE", outstr);
1406
void ical_property_X_MS_OLK_DIRECTORY(struct exchange2ical *exchange2ical)
1409
if(!exchange2ical->Directory) return;
1410
if(!(*exchange2ical->Directory)) return;
1412
ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-DIRECTORY", exchange2ical->Directory);
1416
void ical_property_X_MS_OLK_MWSURL(struct exchange2ical *exchange2ical)
1419
if(!exchange2ical->MWSURL) return;
1421
ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-MWSURL", exchange2ical->MWSURL);
1425
void ical_property_X_MS_OLK_NETSHOWURL(struct exchange2ical *exchange2ical)
1428
if(!exchange2ical->NetShowURL) return;
1429
if(!(*exchange2ical->NetShowURL)) return;
1431
ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-NETSHOWURL", exchange2ical->NetShowURL);
1434
void ical_property_X_MS_OLK_ONLINEPASSWORD(struct exchange2ical *exchange2ical)
1437
if(!exchange2ical->OnlinePassword) return;
1438
if(!(*exchange2ical->OnlinePassword)) return;
1440
ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-ONLINEPASSWORD", exchange2ical->OnlinePassword);
1443
void ical_property_X_MS_OLK_ORGALIAS(struct exchange2ical *exchange2ical)
1446
if(!exchange2ical->OrgAlias) return;
1447
if(!(*exchange2ical->OrgAlias)) return;
1449
ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-ORGALIAS", exchange2ical->OrgAlias);
1453
// TODO: double check this - need an example.
1454
void ical_property_X_MS_OLK_SENDER(struct exchange2ical *exchange2ical)
1457
icalparameter *param;
1461
if (!exchange2ical->apptStateFlags) return;
1462
if (!(*exchange2ical->apptStateFlags & 0x1)) return;
1463
if (!exchange2ical->SenderName) return;
1465
if (exchange2ical->SenderEmailAddress) {
1466
snprintf(outstr, 200, "mailto:%s",exchange2ical->SenderEmailAddress);
1467
prop = icalproperty_new_x(outstr);
1469
prop = icalproperty_new_x("invalid:nomail");
1472
icalproperty_set_x_name(prop, "X-MS-OLK-SENDER");
1473
icalcomponent_add_property(exchange2ical->vevent, prop);
1475
param = icalparameter_new_cn(exchange2ical->SenderName);
1476
icalproperty_add_parameter(prop, param);