~ubuntu-branches/ubuntu/oneiric/openchange/oneiric

« back to all changes in this revision

Viewing changes to libexchange2ical/exchange2ical_property.c

  • Committer: Bazaar Package Importer
  • Author(s): Jelmer Vernooij
  • Date: 2010-08-23 14:14:19 UTC
  • mfrom: (3.2.2 experimental)
  • Revision ID: james.westby@ubuntu.com-20100823141419-u35vdnmilt8ghudh
Tags: 1:0.9+svn2132-1
* New upstream snapshot.
* Bump standards version to 3.9.1 (no changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Convert Exchange appointments and meetings to ICAL files
 
3
 
 
4
   OpenChange Project
 
5
 
 
6
   Copyright (C) Julien Kerihuel 2008
 
7
 
 
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.
 
12
   
 
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.
 
17
   
 
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/>.
 
20
*/
 
21
 
 
22
#include "libexchange2ical/libexchange2ical.h"
 
23
#include <ldb.h>
 
24
 
 
25
struct RRULE_byday {
 
26
        uint16_t        DayOfWeek;
 
27
        const char      *DayName;
 
28
};
 
29
 
 
30
static const struct RRULE_byday RRULE_byday[] = {
 
31
        { 0x0000,       "SU" },
 
32
        { 0x0001,       "MO" },
 
33
        { 0x0002,       "TU" },
 
34
        { 0x0003,       "WE" },
 
35
        { 0x0004,       "TH" },
 
36
        { 0x0005,       "FR" },
 
37
        { 0x0006,       "SA" },
 
38
        { 0x0007,       NULL }
 
39
};
 
40
 
 
41
static const char *get_filename(const char *filename)
 
42
{
 
43
        const char *substr;
 
44
 
 
45
        if (!filename) return NULL;
 
46
 
 
47
        substr = rindex(filename, '/');
 
48
        if (substr) return substr;
 
49
 
 
50
        return filename;
 
51
}
 
52
 
 
53
 
 
54
void ical_property_ATTACH(struct exchange2ical *exchange2ical)
 
55
{
 
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;
 
64
        unsigned int                    i;
 
65
        uint32_t                        count;
 
66
        struct SRow                     aRow2;
 
67
 
 
68
        
 
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);
 
76
                
 
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);
 
80
 
 
81
                        if (retval == MAPI_E_SUCCESS) {
 
82
 
 
83
                                SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x7,
 
84
                                                                          PR_ATTACH_FILENAME,
 
85
                                                                          PR_ATTACH_LONG_FILENAME,
 
86
                                                                          PR_ATTACH_METHOD,
 
87
                                                                          PR_ATTACHMENT_FLAGS,
 
88
                                                                          PR_ATTACHMENT_HIDDEN,
 
89
                                                                          PR_ATTACH_MIME_TAG,
 
90
                                                                          PR_ATTACH_DATA_BIN
 
91
                                                                          );
 
92
                                                                          
 
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) {
 
97
 
 
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;
 
104
                                        DATA_BLOB               body;
 
105
                                        icalattach              *icalattach = NULL;
 
106
                                        icalproperty            *prop = NULL;
 
107
                                        icalparameter           *param = NULL;
 
108
                                                
 
109
                                        
 
110
                                        aRow2.ulAdrEntryPad = 0;
 
111
                                        aRow2.cValues = count;
 
112
                                        aRow2.lpProps = lpProps;
 
113
                                        
 
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);
 
117
 
 
118
                                        if(!(*attachmentFlags & 0x00000007) 
 
119
                                                && (*attachMethod == 0x00000001) 
 
120
                                                && (!attachmentHidden || !(*attachmentHidden))) {
 
121
 
 
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);
 
126
                                                
 
127
                                                /*Create a new icalattach from above data*/
 
128
                                                icalattach = icalattach_new_from_data((unsigned char *)data,0,0);
 
129
                                                
 
130
                                                /*Add attach property to vevent component*/
 
131
                                                prop = icalproperty_new_attach(icalattach);
 
132
                                                icalcomponent_add_property(exchange2ical->vevent, prop);
 
133
 
 
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));
 
138
                                                }
 
139
                                                
 
140
                                                /* fmttype parameter */
 
141
                                                fmttype = (const char *) octool_get_propval(&aRow2, PR_ATTACH_MIME_TAG);
 
142
                                                if(fmttype) {
 
143
                                                        param = icalparameter_new_fmttype(fmttype);
 
144
                                                        icalproperty_add_parameter(prop, param);
 
145
                                                }
 
146
                                                
 
147
                                                /* ENCODING parameter */
 
148
                                                param =icalparameter_new_encoding(ICAL_ENCODING_BASE64);
 
149
                                                icalproperty_add_parameter(prop,param);
 
150
                                                
 
151
                                                /* VALUE parameter */
 
152
                                                param=icalparameter_new_value(ICAL_VALUE_BINARY);
 
153
                                                icalproperty_add_parameter(prop,param);
 
154
                                                
 
155
                                                /* X-FILENAME parameter */
 
156
                                                param = icalparameter_new_x(attach_filename);
 
157
                                                icalparameter_set_xname(param,"X-FILENAME");
 
158
                                                icalproperty_add_parameter(prop,param);
 
159
                                        }
 
160
                                        MAPIFreeBuffer(lpProps);
 
161
                                }
 
162
                        }
 
163
                }
 
164
        }
 
165
        mapi_object_release(&obj_tb_attach);
 
166
}
 
167
 
 
168
 
 
169
// TODO: check this - need an example
 
170
void ical_property_ATTENDEE(struct exchange2ical *exchange2ical)
 
171
{
 
172
        uint32_t        i;
 
173
        const char      *smtp;
 
174
        const char      *display_name;
 
175
        uint32_t        *RecipientFlags;
 
176
        uint32_t        *RecipientType;
 
177
        uint32_t        *TrackStatus;
 
178
        struct SRowSet  *SRowSet;
 
179
 
 
180
        /* Sanity check */
 
181
        if (!exchange2ical->apptStateFlags) return;
 
182
        if (!(*exchange2ical->apptStateFlags & 0x1)) return;
 
183
        SRowSet = &(exchange2ical->Recipients.SRowSet);
 
184
 
 
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);
 
192
 
 
193
 
 
194
                if (RecipientFlags && !(*RecipientFlags & 0x20) && !(*RecipientFlags & 0x2) &&
 
195
                    (RecipientType && *RecipientType)) {
 
196
                        icalproperty *prop;
 
197
                        icalparameter *cn;
 
198
                        icalparameter *participantType;
 
199
                        enum icalparameter_partstat     partstat = ICAL_PARTSTAT_NONE;
 
200
 
 
201
                        if (smtp) {
 
202
                                char *mailtoURL;
 
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);
 
207
                        } else {
 
208
                                prop = icalproperty_new_attendee("invalid:nomail");
 
209
                                icalcomponent_add_property(exchange2ical->vevent, prop);
 
210
                        }
 
211
 
 
212
                        if (display_name) {
 
213
                                cn = icalparameter_new_cn(display_name);
 
214
                                icalproperty_add_parameter(prop, cn);
 
215
                        }
 
216
 
 
217
                        if (*RecipientType == 0x3) {
 
218
                                icalparameter *cutype = icalparameter_new_cutype(ICAL_CUTYPE_RESOURCE);
 
219
                                icalproperty_add_parameter(prop, cutype);
 
220
                        }
 
221
 
 
222
                        switch (*RecipientType) {
 
223
                        case 0x00000002:
 
224
                                participantType = icalparameter_new_role(ICAL_ROLE_OPTPARTICIPANT);
 
225
                                icalproperty_add_parameter(prop, participantType);
 
226
                                break;
 
227
                        case 0x00000003:
 
228
                                participantType = icalparameter_new_role(ICAL_ROLE_NONPARTICIPANT);
 
229
                                icalproperty_add_parameter(prop, participantType);
 
230
                                break;
 
231
                        }
 
232
 
 
233
                
 
234
                        
 
235
                        if((exchange2ical->method==ICAL_METHOD_REPLY) || (exchange2ical->method==ICAL_METHOD_COUNTER)){
 
236
                                partstat = exchange2ical->partstat;     
 
237
                        }else if(exchange2ical->method==ICAL_METHOD_PUBLISH){
 
238
                                if(TrackStatus){
 
239
                                        partstat = get_ical_partstat_from_status(*TrackStatus);
 
240
                                }else if(exchange2ical->ResponseStatus){
 
241
                                        partstat = get_ical_partstat_from_status(*exchange2ical->ResponseStatus);
 
242
                                }
 
243
                        }
 
244
                        
 
245
                        if (partstat != ICAL_PARTSTAT_NONE) {
 
246
                                icalparameter *param;
 
247
                                param = icalparameter_new_partstat(partstat);
 
248
                                icalproperty_add_parameter(prop, param);
 
249
                        }
 
250
 
 
251
                        if (exchange2ical->ResponseRequested) {
 
252
                                icalparameter *rsvp;
 
253
                                if (*(exchange2ical->ResponseRequested)) {
 
254
                                        rsvp = icalparameter_new_rsvp(ICAL_RSVP_TRUE);
 
255
                                } else {
 
256
                                        rsvp = icalparameter_new_rsvp(ICAL_RSVP_FALSE);
 
257
                                }
 
258
                                icalproperty_add_parameter(prop, rsvp);
 
259
                        }
 
260
                }
 
261
        }
 
262
}
 
263
 
 
264
 
 
265
void ical_property_CATEGORIES(struct exchange2ical *exchange2ical)
 
266
{
 
267
        uint32_t        i;
 
268
        icalproperty    *prop;
 
269
 
 
270
        /* Sanity check */
 
271
        if (!exchange2ical->Keywords) return;
 
272
        if (!exchange2ical->Keywords->cValues) return;
 
273
 
 
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);
 
277
        }
 
278
 
 
279
}
 
280
 
 
281
 
 
282
void ical_property_CLASS(struct exchange2ical *exchange2ical)
 
283
{
 
284
        icalproperty    *prop;
 
285
 
 
286
        /* Sanity check */
 
287
        if (!exchange2ical->sensitivity) return;
 
288
 
 
289
        prop = icalproperty_new_class(get_ical_class(*exchange2ical->sensitivity));
 
290
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
291
}
 
292
 
 
293
 
 
294
void ical_property_CONTACT(struct exchange2ical *exchange2ical)
 
295
{
 
296
        icalproperty    *prop;
 
297
        uint32_t        i;
 
298
 
 
299
        /* Sanity check */
 
300
        if (!exchange2ical->Contacts) return;
 
301
        if (!exchange2ical->Contacts->cValues) return;
 
302
 
 
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);
 
306
        }
 
307
}
 
308
 
 
309
 
 
310
void ical_property_CREATED(struct exchange2ical *exchange2ical)
 
311
{
 
312
        icalproperty            *prop;
 
313
        struct icaltimetype     icaltime;
 
314
 
 
315
        /* Sanity check */
 
316
        if (!exchange2ical->created) return;
 
317
 
 
318
        icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->created);
 
319
 
 
320
        prop = icalproperty_new_created(icaltime);
 
321
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
322
}
 
323
 
 
324
void ical_property_DTSTART(struct exchange2ical *exchange2ical)
 
325
{
 
326
        icalproperty            *prop;
 
327
        icalparameter           *tzid;
 
328
        struct icaltimetype     icaltime;
 
329
 
 
330
        /* Sanity check */
 
331
        if (!exchange2ical->apptStartWhole) return;
 
332
 
 
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);
 
338
        } else {
 
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);
 
345
                } else {
 
346
                        icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptStartWhole);
 
347
                        prop = icalproperty_new_dtstart(icaltime);
 
348
                        icalcomponent_add_property(exchange2ical->vevent, prop);
 
349
                }
 
350
        
 
351
                
 
352
        }
 
353
}
 
354
 
 
355
 
 
356
void ical_property_DTEND(struct exchange2ical *exchange2ical)
 
357
{
 
358
        icalproperty            *prop;
 
359
        icalparameter           *tzid;
 
360
        struct icaltimetype     icaltime;
 
361
 
 
362
        /* Sanity check */
 
363
        if (!exchange2ical->apptEndWhole) return;
 
364
 
 
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);
 
370
        } else {
 
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);
 
377
                } else {
 
378
                        icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptEndWhole);
 
379
                        prop = icalproperty_new_dtend(icaltime);
 
380
                        icalcomponent_add_property(exchange2ical->vevent, prop);
 
381
                }
 
382
                
 
383
        }
 
384
}
 
385
 
 
386
 
 
387
void ical_property_DTSTAMP(struct exchange2ical *exchange2ical)
 
388
{
 
389
        icalproperty            *prop;
 
390
        struct icaltimetype     icaltime;
 
391
        struct tm               *tm;
 
392
        icalparameter           *tzid;
 
393
        time_t                  t;
 
394
 
 
395
        /* Sanity check */
 
396
        /*If OwnerCriticalChange field is null, get time system time*/
 
397
        if (!exchange2ical->OwnerCriticalChange) {
 
398
                t=time(NULL);
 
399
                tm = gmtime(&t);
 
400
                icaltime = get_icaltimetype_from_tm_UTC(tm);
 
401
                prop = icalproperty_new_dtstamp(icaltime);
 
402
                icalcomponent_add_property(exchange2ical->vevent, prop);
 
403
                return;
 
404
        } else {
 
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);
 
411
                }
 
412
        }
 
413
}
 
414
 
 
415
 
 
416
void ical_property_DESCRIPTION(struct exchange2ical *exchange2ical)
 
417
{
 
418
        icalproperty    *prop;
 
419
 
 
420
        if (exchange2ical->method == ICAL_METHOD_REPLY) return;
 
421
        if (!exchange2ical->body) return;
 
422
 
 
423
        prop = icalproperty_new_description(exchange2ical->body);
 
424
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
425
}
 
426
 
 
427
 
 
428
void ical_property_EXDATE(struct exchange2ical *exchange2ical)
 
429
{
 
430
        uint32_t        i;
 
431
        uint32_t        j;
 
432
        uint8_t         modified;
 
433
        struct icaltimetype     icaltime;
 
434
        struct icaltimetype     dttime;
 
435
 
 
436
        icalproperty    *prop;
 
437
        struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
 
438
 
 
439
        /* Sanity check */
 
440
        if (exchange2ical->Recurring && (*exchange2ical->Recurring == 0x0)) return;
 
441
        if (!pat) return;
 
442
        if (!pat->DeletedInstanceCount) return;
 
443
 
 
444
        for (i = 0; i < pat->DeletedInstanceCount; i++) {
 
445
                modified=0;
 
446
                if(pat->ModifiedInstanceDates && pat->ModifiedInstanceCount){
 
447
                        for(j=0; j < pat->ModifiedInstanceCount; j++){
 
448
                                if(pat->ModifiedInstanceDates[j]==pat->DeletedInstanceDates[i]){
 
449
                                        modified=1;
 
450
                                        break;
 
451
                                }
 
452
                        }
 
453
                }
 
454
                /* If this is an all-day appointment */
 
455
                if (!modified && exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
 
456
                        struct tm       tm;
 
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 */
 
464
                        struct tm       tm;
 
465
                        tm = get_tm_from_minutes_UTC(pat->DeletedInstanceDates[i]);
 
466
                        icaltime= get_icaltimetype_from_tm(&tm);
 
467
 
 
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;
 
474
                                }
 
475
 
 
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);
 
480
                        } else {
 
481
                                /*Get time from dtstart*/
 
482
                                icaltime.is_utc = 1;
 
483
                                if (exchange2ical->apptEndWhole){
 
484
                                        dttime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptStartWhole);
 
485
                                        icaltime.hour   = dttime.hour;
 
486
                                        icaltime.minute = dttime.minute;
 
487
                                }
 
488
                                prop = icalproperty_new_exdate(icaltime);
 
489
                                icalcomponent_add_property(exchange2ical->vevent, prop);
 
490
                        }
 
491
                }               
 
492
                
 
493
        }
 
494
}
 
495
 
 
496
 
 
497
void ical_property_LAST_MODIFIED(struct exchange2ical *exchange2ical)
 
498
{
 
499
        icalproperty            *prop;
 
500
        struct icaltimetype     icaltime;
 
501
        icalparameter           *tzid;
 
502
 
 
503
 
 
504
        /* Sanity check */
 
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);
 
511
        } else {
 
512
                icaltime=get_icaltime_from_FILETIME_UTC(exchange2ical->LastModified);
 
513
                prop = icalproperty_new_lastmodified(icaltime);
 
514
        }
 
515
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
516
}
 
517
 
 
518
 
 
519
void ical_property_LOCATION(struct exchange2ical *exchange2ical)
 
520
{
 
521
        icalproperty *prop;
 
522
        /* Sanity check */
 
523
        if (!exchange2ical->Location) return;
 
524
 
 
525
        prop = icalproperty_new_location(exchange2ical->Location);
 
526
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
527
}
 
528
 
 
529
 
 
530
void ical_property_ORGANIZER(struct exchange2ical *exchange2ical)
 
531
{
 
532
        const char      *smtp;
 
533
        const char      *display_name;
 
534
        uint32_t        *RecipientFlags;
 
535
        uint32_t        *RecipientType;
 
536
        uint32_t        i;
 
537
        struct SRowSet  *SRowSet;
 
538
 
 
539
        /* Sanity check */
 
540
        if (!exchange2ical->apptStateFlags) return;
 
541
        if (!(*exchange2ical->apptStateFlags & 0x1)) return;
 
542
 
 
543
        SRowSet = &(exchange2ical->Recipients.SRowSet);
 
544
 
 
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);
 
551
 
 
552
                if (RecipientFlags && !(*RecipientFlags & 0x20) &&
 
553
                    ((*RecipientFlags & 0x2) || (RecipientType && !*RecipientType))) {
 
554
                        icalproperty *prop;
 
555
                        icalparameter *cn;
 
556
 
 
557
                        if (smtp) {
 
558
                                char *mailtoURL;
 
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);
 
564
                        } else {
 
565
                                prop = icalproperty_new_organizer("invalid:nomail");
 
566
                                icalcomponent_add_property(exchange2ical->vevent, prop);
 
567
                        }
 
568
 
 
569
                        if (display_name) {
 
570
                                cn = icalparameter_new_cn(display_name);
 
571
                                icalproperty_add_parameter(prop, cn);
 
572
                        }
 
573
                }
 
574
        }
 
575
}
 
576
 
 
577
 
 
578
void ical_property_PRIORITY(struct exchange2ical *exchange2ical)
 
579
{
 
580
        icalproperty *prop;
 
581
        /* Sanity check */
 
582
        if (!exchange2ical->Importance) return;
 
583
 
 
584
        switch (*exchange2ical->Importance) {
 
585
        case 0x00000000:
 
586
                prop = icalproperty_new_priority(9);
 
587
                break;
 
588
        case 0x00000001:
 
589
                prop = icalproperty_new_priority(5);
 
590
                break;
 
591
        case 0x00000002:
 
592
                prop = icalproperty_new_priority(1);
 
593
                break;
 
594
        default:
 
595
                prop = icalproperty_new_priority(5);
 
596
        }
 
597
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
598
}
 
599
 
 
600
 
 
601
void ical_property_RRULE_Daily(struct exchange2ical *exchange2ical)
 
602
{
 
603
        struct icalrecurrencetype recurrence;
 
604
        icalproperty *prop;
 
605
        struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
 
606
 
 
607
 
 
608
        icalrecurrencetype_clear(&recurrence);
 
609
        recurrence.freq = ICAL_DAILY_RECURRENCE;
 
610
        recurrence.interval = (pat->Period / 1440);
 
611
 
 
612
        if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
 
613
                recurrence.count = pat->OccurrenceCount;
 
614
        }
 
615
        prop = icalproperty_new_rrule(recurrence);
 
616
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
617
}
 
618
 
 
619
 
 
620
void ical_property_RRULE_Weekly(struct exchange2ical *exchange2ical)
 
621
{
 
622
        struct icalrecurrencetype recurrence;
 
623
        icalproperty *prop;
 
624
        struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
 
625
        uint32_t rdfDaysBitmask = pat->PatternTypeSpecific.WeekRecurrencePattern;
 
626
        short idx = 0;
 
627
 
 
628
        icalrecurrencetype_clear(&recurrence);
 
629
        recurrence.freq = ICAL_WEEKLY_RECURRENCE;
 
630
        recurrence.interval = pat->Period;
 
631
        
 
632
        if(pat->Period > 1){
 
633
                switch(pat->FirstDOW){
 
634
                        case FirstDOW_Sunday:
 
635
                                recurrence.week_start=ICAL_SUNDAY_WEEKDAY;
 
636
                                break;
 
637
                        case FirstDOW_Monday:
 
638
                                recurrence.week_start=ICAL_MONDAY_WEEKDAY;
 
639
                                break;
 
640
                        case FirstDOW_Tuesday:
 
641
                                recurrence.week_start=ICAL_TUESDAY_WEEKDAY;
 
642
                                break;
 
643
                        case FirstDOW_Wednesday:
 
644
                                recurrence.week_start=ICAL_WEDNESDAY_WEEKDAY;
 
645
                                break;
 
646
                        case FirstDOW_Thursday:
 
647
                                recurrence.week_start=ICAL_THURSDAY_WEEKDAY;
 
648
                                break;
 
649
                        case FirstDOW_Friday:
 
650
                                recurrence.week_start=ICAL_FRIDAY_WEEKDAY;
 
651
                                break;
 
652
                        case FirstDOW_Saturday:
 
653
                                recurrence.week_start=ICAL_SATURDAY_WEEKDAY;
 
654
                                break;
 
655
                }
 
656
        }
 
657
        
 
658
        if (rdfDaysBitmask & Su) {
 
659
                recurrence.by_day[idx] = ICAL_SUNDAY_WEEKDAY;
 
660
                ++idx;
 
661
        }
 
662
        if (rdfDaysBitmask & M) {
 
663
                recurrence.by_day[idx] = ICAL_MONDAY_WEEKDAY;
 
664
                ++idx;
 
665
        }
 
666
        if (rdfDaysBitmask & Tu) {
 
667
                recurrence.by_day[idx] = ICAL_TUESDAY_WEEKDAY;
 
668
                ++idx;
 
669
        }
 
670
        if (rdfDaysBitmask & W) {
 
671
                recurrence.by_day[idx] = ICAL_WEDNESDAY_WEEKDAY;
 
672
                ++idx;
 
673
        }
 
674
        if (rdfDaysBitmask & Th) {
 
675
                recurrence.by_day[idx] = ICAL_THURSDAY_WEEKDAY;
 
676
                ++idx;
 
677
        }
 
678
        if (rdfDaysBitmask & F) {
 
679
                recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
 
680
                ++idx;
 
681
        }
 
682
        if (rdfDaysBitmask & Sa) {
 
683
                recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
 
684
                ++idx;
 
685
        }
 
686
        recurrence.by_day[idx] = ICAL_RECURRENCE_ARRAY_MAX;
 
687
 
 
688
        if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
 
689
                recurrence.count = pat->OccurrenceCount;
 
690
        }
 
691
 
 
692
        prop = icalproperty_new_rrule(recurrence);
 
693
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
694
}
 
695
 
 
696
 
 
697
void ical_property_RRULE_Monthly(struct exchange2ical *exchange2ical)
 
698
{
 
699
        struct icalrecurrencetype recurrence;
 
700
        icalproperty *prop;
 
701
        struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
 
702
        uint32_t day = pat->PatternTypeSpecific.Day;
 
703
 
 
704
        icalrecurrencetype_clear(&recurrence);
 
705
        recurrence.freq = ICAL_MONTHLY_RECURRENCE;
 
706
        recurrence.interval = pat->Period;
 
707
 
 
708
        if (day == 0x0000001F) {
 
709
                recurrence.by_month_day[0] = -1;
 
710
        } else {
 
711
                recurrence.by_month_day[0] = day;
 
712
        }
 
713
        recurrence.by_month_day[1] = ICAL_RECURRENCE_ARRAY_MAX;
 
714
 
 
715
        if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
 
716
                recurrence.count = pat->OccurrenceCount;
 
717
        }
 
718
 
 
719
        prop = icalproperty_new_rrule(recurrence);
 
720
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
721
}
 
722
 
 
723
 
 
724
void ical_property_RRULE_NthMonthly(struct exchange2ical *exchange2ical)
 
725
{
 
726
        struct icalrecurrencetype recurrence;
 
727
        icalproperty *prop;
 
728
        struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
 
729
        uint32_t rdfDaysBitmask = pat->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern;
 
730
        short idx = 0;
 
731
        enum RecurrenceN setpos = pat->PatternTypeSpecific.MonthRecurrencePattern.N;
 
732
 
 
733
        icalrecurrencetype_clear(&recurrence);
 
734
        recurrence.freq = ICAL_MONTHLY_RECURRENCE;
 
735
        recurrence.interval = pat->Period;
 
736
 
 
737
        if (rdfDaysBitmask & Su) {
 
738
                recurrence.by_day[idx] = ICAL_SUNDAY_WEEKDAY;
 
739
                ++idx;
 
740
        }
 
741
        if (rdfDaysBitmask & M) {
 
742
                recurrence.by_day[idx] = ICAL_MONDAY_WEEKDAY;
 
743
                ++idx;
 
744
        }
 
745
        if (rdfDaysBitmask & Tu) {
 
746
                recurrence.by_day[idx] = ICAL_TUESDAY_WEEKDAY;
 
747
                ++idx;
 
748
        }
 
749
        if (rdfDaysBitmask & W) {
 
750
                recurrence.by_day[idx] = ICAL_WEDNESDAY_WEEKDAY;
 
751
                ++idx;
 
752
        }
 
753
        if (rdfDaysBitmask & Th) {
 
754
                recurrence.by_day[idx] = ICAL_THURSDAY_WEEKDAY;
 
755
                ++idx;
 
756
        }
 
757
        if (rdfDaysBitmask & F) {
 
758
                recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
 
759
                ++idx;
 
760
        }
 
761
        if (rdfDaysBitmask & Sa) {
 
762
                recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
 
763
                ++idx;
 
764
        }
 
765
        recurrence.by_day[idx] = ICAL_RECURRENCE_ARRAY_MAX;
 
766
 
 
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;
 
782
        }
 
783
 
 
784
        if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
 
785
                recurrence.count = pat->OccurrenceCount;
 
786
        }
 
787
 
 
788
        prop = icalproperty_new_rrule(recurrence);
 
789
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
790
}
 
791
 
 
792
 
 
793
void ical_property_RRULE_Yearly(struct exchange2ical *exchange2ical)
 
794
{
 
795
        struct icalrecurrencetype recurrence;
 
796
        icalproperty *prop;
 
797
        struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
 
798
        uint32_t day = pat->PatternTypeSpecific.Day;
 
799
        struct icaltimetype icaltime;
 
800
 
 
801
        icalrecurrencetype_clear(&recurrence);
 
802
        recurrence.freq = ICAL_YEARLY_RECURRENCE;
 
803
        recurrence.interval = (pat->Period / 12);
 
804
 
 
805
        if (day == 0x0000001F) {
 
806
                recurrence.by_month_day[0] = -1;
 
807
        } else {
 
808
                recurrence.by_month_day[0] = day;
 
809
        }
 
810
        recurrence.by_month_day[1] = ICAL_RECURRENCE_ARRAY_MAX;
 
811
 
 
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;
 
815
 
 
816
 
 
817
        
 
818
        if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
 
819
                recurrence.count = pat->OccurrenceCount;
 
820
        } 
 
821
        
 
822
        prop = icalproperty_new_rrule(recurrence);
 
823
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
824
}
 
825
 
 
826
void ical_property_RRULE_NthYearly(struct exchange2ical *exchange2ical)
 
827
{
 
828
        struct icalrecurrencetype recurrence;
 
829
        icalproperty *prop;
 
830
        struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
 
831
        uint32_t rdfDaysBitmask = pat->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern;
 
832
        short idx = 0;
 
833
        enum RecurrenceN setpos = pat->PatternTypeSpecific.MonthRecurrencePattern.N;
 
834
 
 
835
        struct icaltimetype icaltime;
 
836
 
 
837
        icalrecurrencetype_clear(&recurrence);
 
838
        recurrence.freq = ICAL_YEARLY_RECURRENCE;
 
839
        recurrence.interval = (pat->Period / 12);
 
840
 
 
841
        if (rdfDaysBitmask & Su) {
 
842
                recurrence.by_day[idx] = ICAL_SUNDAY_WEEKDAY;
 
843
                ++idx;
 
844
        }
 
845
        if (rdfDaysBitmask & M) {
 
846
                recurrence.by_day[idx] = ICAL_MONDAY_WEEKDAY;
 
847
                ++idx;
 
848
        }
 
849
        if (rdfDaysBitmask & Tu) {
 
850
                recurrence.by_day[idx] = ICAL_TUESDAY_WEEKDAY;
 
851
                ++idx;
 
852
        }
 
853
        if (rdfDaysBitmask & W) {
 
854
                recurrence.by_day[idx] = ICAL_WEDNESDAY_WEEKDAY;
 
855
                ++idx;
 
856
        }
 
857
        if (rdfDaysBitmask & Th) {
 
858
                recurrence.by_day[idx] = ICAL_THURSDAY_WEEKDAY;
 
859
                ++idx;
 
860
        }
 
861
        if (rdfDaysBitmask & F) {
 
862
                recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
 
863
                ++idx;
 
864
        }
 
865
        if (rdfDaysBitmask & Sa) {
 
866
                recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
 
867
                ++idx;
 
868
        }
 
869
        recurrence.by_day[idx] = ICAL_RECURRENCE_ARRAY_MAX;
 
870
 
 
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;
 
886
        }
 
887
 
 
888
        icaltime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole);
 
889
        recurrence.by_month[0] = icaltime.month;
 
890
        recurrence.by_month[1] = ICAL_RECURRENCE_ARRAY_MAX;
 
891
        
 
892
        if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
 
893
                recurrence.count = pat->OccurrenceCount;
 
894
        }
 
895
 
 
896
        prop = icalproperty_new_rrule(recurrence);
 
897
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
898
}
 
899
 
 
900
 
 
901
void ical_property_RRULE(struct exchange2ical *exchange2ical)
 
902
{
 
903
        struct RecurrencePattern *pat;
 
904
 
 
905
        /* Sanity check */
 
906
        if (!(exchange2ical->RecurrencePattern)) return;
 
907
 
 
908
        pat = exchange2ical->RecurrencePattern;
 
909
 
 
910
        switch(pat->PatternType) {
 
911
        case PatternType_Day:
 
912
                ical_property_RRULE_Daily(exchange2ical);
 
913
                break;
 
914
        case PatternType_Week:
 
915
                ical_property_RRULE_Weekly(exchange2ical);
 
916
                break;
 
917
        case PatternType_Month:
 
918
                if ((pat->Period % 12 ) == 0) {
 
919
                        ical_property_RRULE_Yearly(exchange2ical);
 
920
                } else {
 
921
                        ical_property_RRULE_Monthly(exchange2ical);
 
922
                }
 
923
                break;
 
924
        case PatternType_MonthNth:
 
925
                if ((pat->Period % 12 ) == 0) {
 
926
                        ical_property_RRULE_NthYearly(exchange2ical);
 
927
                } else {
 
928
                        ical_property_RRULE_NthMonthly(exchange2ical);
 
929
                }
 
930
                break;
 
931
        default:
 
932
                printf("RRULE pattern type not implemented yet!:0x%x\n", pat->PatternType);
 
933
        }
 
934
}
 
935
 
 
936
void ical_property_RRULE_daylight_standard(icalcomponent* component , struct SYSTEMTIME st)
 
937
{
 
938
        struct icalrecurrencetype recurrence;
 
939
        icalproperty *prop;
 
940
        
 
941
        icalrecurrencetype_clear(&recurrence);
 
942
        recurrence.freq = ICAL_YEARLY_RECURRENCE;
 
943
 
 
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 */
 
948
                if (st.wDay==5){
 
949
                        /* Last occurrence of day in the month*/
 
950
                        recurrence.by_day[0] = -1 * (st.wDayOfWeek + 9);
 
951
                }else{
 
952
                        /* st.wDay occurrence of day in the month */
 
953
                        recurrence.by_day[0] = (st.wDayOfWeek + 1 + st.wDay*8);
 
954
                }
 
955
                
 
956
        }else{
 
957
                recurrence.by_month_day[0]=st.wDay;
 
958
                recurrence.by_month[0]=st.wMonth;
 
959
        }
 
960
 
 
961
        
 
962
        prop = icalproperty_new_rrule(recurrence);
 
963
        icalcomponent_add_property(component, prop);
 
964
}
 
965
 
 
966
 
 
967
void ical_property_RECURRENCE_ID(struct exchange2ical *exchange2ical)
 
968
{       
 
969
        struct icaltimetype     icaltime;
 
970
        icalproperty            *prop;
 
971
        icalparameter           *tzid;
 
972
        struct GlobalObjectId   *GlbObjId;
 
973
 
 
974
        
 
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);
 
981
                } else {
 
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);
 
988
                        } else {
 
989
                                icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->ExceptionReplaceTime);
 
990
                                prop = icalproperty_new_recurrenceid(icaltime);
 
991
                                icalcomponent_add_property(exchange2ical->vevent, prop);
 
992
                        }
 
993
                }
 
994
        } else if (exchange2ical->GlobalObjectId){
 
995
                GlbObjId = get_GlobalObjectId(exchange2ical->mem_ctx, exchange2ical->GlobalObjectId);
 
996
                if(GlbObjId){
 
997
                        icaltime=get_icaldate_from_GlobalObjectId(GlbObjId);
 
998
                        prop = icalproperty_new_recurrenceid(icaltime);
 
999
                        icalcomponent_add_property(exchange2ical->vevent, prop);
 
1000
                        talloc_free(GlbObjId);
 
1001
 
 
1002
                }
 
1003
        }
 
1004
        
 
1005
}
 
1006
 
 
1007
 
 
1008
void ical_property_RESOURCES(struct exchange2ical *exchange2ical)
 
1009
{
 
1010
        char            *NonSendableBcc = NULL;
 
1011
        icalproperty    *prop;
 
1012
 
 
1013
        /* Sanity check */
 
1014
        if (!exchange2ical->NonSendableBcc) return;
 
1015
        
 
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);
 
1021
}
 
1022
 
 
1023
 
 
1024
void ical_property_SEQUENCE(struct exchange2ical *exchange2ical)
 
1025
{
 
1026
        icalproperty *prop;
 
1027
        if (!exchange2ical->Sequence) {
 
1028
                prop = icalproperty_new_sequence(0);
 
1029
        } else {
 
1030
                prop = icalproperty_new_sequence(*(exchange2ical->Sequence));
 
1031
        }
 
1032
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
1033
}
 
1034
 
 
1035
 
 
1036
void ical_property_SUMMARY(struct exchange2ical *exchange2ical)
 
1037
{
 
1038
        icalproperty *prop;
 
1039
        icalparameter *language;
 
1040
 
 
1041
        if (exchange2ical->Subject) {
 
1042
                prop = icalproperty_new_summary(exchange2ical->Subject);
 
1043
        } else {
 
1044
                prop = icalproperty_new_summary("");
 
1045
        }
 
1046
 
 
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);
 
1051
        }
 
1052
 
 
1053
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
1054
}
 
1055
 
 
1056
 
 
1057
void ical_property_TRANSP(struct exchange2ical *exchange2ical)
 
1058
{
 
1059
        icalproperty *prop;
 
1060
 
 
1061
        /* Sanity check */
 
1062
        if (!exchange2ical->BusyStatus) return;
 
1063
 
 
1064
        switch (*exchange2ical->BusyStatus) {
 
1065
        case 0x00000000:
 
1066
                prop = icalproperty_new_transp(ICAL_TRANSP_TRANSPARENT);
 
1067
                break;
 
1068
        case 0x00000001:
 
1069
        case 0x00000002:
 
1070
        case 0x00000003:
 
1071
                prop = icalproperty_new_transp(ICAL_TRANSP_OPAQUE);
 
1072
                break;
 
1073
        default:
 
1074
                prop = icalproperty_new_transp(ICAL_TRANSP_NONE);
 
1075
        }
 
1076
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
1077
}
 
1078
 
 
1079
 
 
1080
void ical_property_TRIGGER(struct exchange2ical *exchange2ical)
 
1081
{
 
1082
        struct icaltriggertype duration;
 
1083
        icalproperty *prop;
 
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);
 
1089
        } else {
 
1090
                duration = icaltriggertype_from_int(*(exchange2ical->ReminderDelta) * -1 * 60);
 
1091
                prop = icalproperty_new_trigger(duration);
 
1092
                icalcomponent_add_property(exchange2ical->valarm, prop);
 
1093
        }
 
1094
}
 
1095
 
 
1096
 
 
1097
#define GLOBAL_OBJECT_ID_DATA_START     "\x76\x43\x61\x6c\x2d\x55\x69\x64\x01\x00\x00\x00"
 
1098
 
 
1099
void ical_property_UID(struct exchange2ical *exchange2ical)
 
1100
{
 
1101
        uint32_t                i;
 
1102
        const char              *uid;
 
1103
        char*                   outstr;
 
1104
        struct GlobalObjectId   *GlbObjId;
 
1105
        icalproperty            *prop;
 
1106
 
 
1107
        outstr = talloc_strdup(exchange2ical->mem_ctx, "uid");
 
1108
        
 
1109
        if(exchange2ical->GlobalObjectId){
 
1110
                GlbObjId = get_GlobalObjectId(exchange2ical->mem_ctx, exchange2ical->GlobalObjectId);
 
1111
        }
 
1112
        
 
1113
      
 
1114
        if (exchange2ical->GlobalObjectId && GlbObjId) {
 
1115
                if (GlbObjId->Size >= 12 && (0 == memcmp(GlbObjId->Data, GLOBAL_OBJECT_ID_DATA_START, 12))) {
 
1116
                        fflush(0);
 
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++) {
 
1120
                                char objID[6];
 
1121
                                snprintf(objID, 6, "%.2X", exchange2ical->GlobalObjectId->lpb[i]);
 
1122
                                outstr = talloc_strdup_append(outstr, objID);
 
1123
                        }
 
1124
 
 
1125
                        uid = (const char *)&(GlbObjId->Data[13]);
 
1126
                        outstr = talloc_strdup_append(outstr, uid);
 
1127
                } else {
 
1128
                        fflush(0);
 
1129
                        for (i = 0; i < 16; i++) {
 
1130
                                char objID[6];
 
1131
                                snprintf(objID, 6, "%.2X", exchange2ical->GlobalObjectId->lpb[i]);
 
1132
                                outstr = talloc_strdup_append(outstr, objID);
 
1133
                        }
 
1134
                        /* YH, YL, Month and D must be set to 0 */
 
1135
                        outstr = talloc_strdup_append(outstr, "00000000");
 
1136
 
 
1137
                        for (i = 20; i < exchange2ical->GlobalObjectId->cb; i++) {
 
1138
                                char objID[6];
 
1139
                                snprintf(objID, 6, "%.2X", exchange2ical->GlobalObjectId->lpb[i]);
 
1140
                                outstr = talloc_strdup_append(outstr, objID);
 
1141
                        }
 
1142
                }
 
1143
                talloc_free(GlbObjId);
 
1144
        } else {
 
1145
                char objID[32];
 
1146
                snprintf(objID, 32, "%i", exchange2ical->idx);
 
1147
                outstr = talloc_strdup(outstr, objID);
 
1148
        }
 
1149
        
 
1150
        prop = icalproperty_new_uid(outstr);
 
1151
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
1152
        talloc_free(outstr);
 
1153
}
 
1154
 
 
1155
 
 
1156
static icalproperty * ical_property_add_x_property_value(icalcomponent *parent, const char* propname, const char* value)
 
1157
{
 
1158
        icalproperty *prop;
 
1159
        icalvalue *icalText;
 
1160
 
 
1161
        /* Sanity checks */
 
1162
        if (!parent) return NULL;
 
1163
        if (!propname) return NULL;
 
1164
        if (!value) return NULL;
 
1165
 
 
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);
 
1171
        return prop;
 
1172
}
 
1173
 
 
1174
void ical_property_X_ALT_DESC(struct exchange2ical *exchange2ical)
 
1175
{
 
1176
        icalproperty *prop;
 
1177
        icalparameter *param;
 
1178
        
 
1179
        /*sanity check */
 
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);        
 
1184
}
 
1185
 
 
1186
void ical_property_X_MICROSOFT_CDO_ATTENDEE_CRITICAL_CHANGE(struct exchange2ical *exchange2ical)
 
1187
{
 
1188
        struct tm       *tm;
 
1189
        char            outstr[200];
 
1190
 
 
1191
        /* Sanity check */
 
1192
        if (!exchange2ical->AttendeeCriticalChange) return;
 
1193
 
 
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);
 
1197
}
 
1198
 
 
1199
 
 
1200
void ical_property_X_MICROSOFT_CDO_BUSYSTATUS(struct exchange2ical *exchange2ical)
 
1201
{
 
1202
        /*sanity check*/
 
1203
        if(!exchange2ical->BusyStatus) return;
 
1204
        
 
1205
        switch (*exchange2ical->BusyStatus) {
 
1206
        case 0x00000000:
 
1207
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "FREE");
 
1208
                break;
 
1209
        case 0x00000001:
 
1210
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "TENTATIVE");
 
1211
                break;
 
1212
        case 0x00000002:
 
1213
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "BUSY");
 
1214
                break;
 
1215
        case 0x00000003:
 
1216
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "OOF");
 
1217
                break;
 
1218
        }
 
1219
}
 
1220
void ical_property_X_MICROSOFT_MSNCALENDAR_IMPORTANCE(struct exchange2ical *exchange2ical)
 
1221
{
 
1222
        /* Sanity check */
 
1223
        if (!exchange2ical->Importance) return;
 
1224
 
 
1225
        switch (*exchange2ical->Importance) {
 
1226
        case 0x00000000:
 
1227
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-MSNCALENDAR-IMPORTANCE", "0");
 
1228
                break;
 
1229
        case 0x00000001:
 
1230
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-MSNCALENDAR-IMPORTANCE", "1");
 
1231
                break;
 
1232
        case 0x00000002:
 
1233
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-MSNCALENDAR-IMPORTANCE", "2");
 
1234
                break;
 
1235
        }
 
1236
}
 
1237
 
 
1238
void ical_property_X_MICROSOFT_CDO_INTENDEDSTATUS(struct exchange2ical *exchange2ical)
 
1239
{
 
1240
        if (!exchange2ical->IntendedBusyStatus) return;
 
1241
 
 
1242
        switch (*exchange2ical->IntendedBusyStatus) {
 
1243
        case 0x00000000:
 
1244
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "FREE");
 
1245
                break;
 
1246
        case 0x00000001:
 
1247
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "TENTATIVE");
 
1248
                break;
 
1249
        case 0x00000002:
 
1250
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "BUSY");
 
1251
                break;
 
1252
        case 0x00000003:
 
1253
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "OOF");
 
1254
                break;
 
1255
        }
 
1256
}
 
1257
 
 
1258
 
 
1259
void ical_property_X_MICROSOFT_CDO_OWNERAPPTID(struct exchange2ical *exchange2ical)
 
1260
{
 
1261
        char outstr[200];
 
1262
        /* Sanity check */
 
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);
 
1266
}
 
1267
 
 
1268
 
 
1269
void ical_property_X_MICROSOFT_CDO_OWNER_CRITICAL_CHANGE(struct exchange2ical *exchange2ical)
 
1270
{
 
1271
        struct tm       *tm;
 
1272
        char            outstr[200];
 
1273
        
 
1274
        /* Sanity check */
 
1275
        if (!exchange2ical->OwnerCriticalChange) return;
 
1276
 
 
1277
 
 
1278
        tm = get_tm_from_FILETIME(exchange2ical->OwnerCriticalChange);
 
1279
        
 
1280
 
 
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);
 
1283
}
 
1284
 
 
1285
 
 
1286
void ical_property_X_MICROSOFT_CDO_REPLYTIME(struct exchange2ical *exchange2ical)
 
1287
{
 
1288
        struct tm       *tm;
 
1289
        char            outstr[200];
 
1290
 
 
1291
        /* Sanity check */
 
1292
        if (!exchange2ical->apptReplyTime) return;
 
1293
 
 
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);
 
1297
}
 
1298
 
 
1299
 
 
1300
void ical_property_X_MICROSOFT_DISALLOW_COUNTER(struct exchange2ical *exchange2ical)
 
1301
{
 
1302
        /* Sanity check */
 
1303
        if (!exchange2ical->NotAllowPropose) return;
 
1304
 
 
1305
        if (*(exchange2ical->NotAllowPropose) == true) {
 
1306
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-DISALLOW-COUNTER", "TRUE");
 
1307
        } else {
 
1308
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-DISALLOW-COUNTER", "FALSE");
 
1309
        }
 
1310
}
 
1311
 
 
1312
 
 
1313
void ical_property_X_MS_OLK_ALLOWEXTERNCHECK(struct exchange2ical *exchange2ical)
 
1314
{
 
1315
        /* Sanity check */
 
1316
        if (!exchange2ical->AllowExternCheck) return;
 
1317
 
 
1318
        if (*(exchange2ical->AllowExternCheck) == true) {
 
1319
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-ALLOWEXTERNCHECK", "TRUE");
 
1320
        } else {
 
1321
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-ALLOWEXTERNCHECK", "FALSE");
 
1322
        }
 
1323
}
 
1324
 
 
1325
 
 
1326
void ical_property_X_MS_OLK_APPTLASTSEQUENCE(struct exchange2ical *exchange2ical)
 
1327
{
 
1328
        char outstr[20];
 
1329
        /* Sanity check */
 
1330
        if (!exchange2ical->apptLastSequence) return;
 
1331
 
 
1332
        snprintf(outstr, 20, "%d", *exchange2ical->apptLastSequence);
 
1333
        ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-APPTLASTSEQUENCE", outstr);
 
1334
}
 
1335
 
 
1336
 
 
1337
void ical_property_X_MS_OLK_APPTSEQTIME(struct exchange2ical *exchange2ical)
 
1338
{
 
1339
        struct tm       *tm = NULL;
 
1340
        char            outstr[200];
 
1341
 
 
1342
        /* Sanity check */
 
1343
        if (!exchange2ical->apptSeqTime) return;
 
1344
 
 
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);
 
1348
}
 
1349
 
 
1350
 
 
1351
void ical_property_X_MS_OLK_AUTOFILLLOCATION(struct exchange2ical *exchange2ical)
 
1352
{
 
1353
        /* Sanity check */
 
1354
        if (!exchange2ical->AutoFillLocation) return;
 
1355
 
 
1356
        if (*(exchange2ical->AutoFillLocation) == true) {
 
1357
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOFILLLOCATION", "TRUE");
 
1358
        } else {
 
1359
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOFILLLOCATION", "FALSE");
 
1360
        }
 
1361
}
 
1362
 
 
1363
 
 
1364
void ical_property_X_MS_OLK_AUTOSTARTCHECK(struct exchange2ical *exchange2ical)
 
1365
{
 
1366
        /* Sanity check */
 
1367
        if (!exchange2ical->AutoStartCheck) return;
 
1368
        if (*(exchange2ical->AutoStartCheck) == true) {
 
1369
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOSTARTCHECK", "TRUE");
 
1370
        } else {
 
1371
                ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOSTARTCHECK", "FALSE");
 
1372
        }
 
1373
}
 
1374
 
 
1375
 
 
1376
void ical_property_X_MS_OLK_COLLABORATEDOC(struct exchange2ical *exchange2ical)
 
1377
{
 
1378
        /* Sanity check */
 
1379
        if (!exchange2ical->CollaborateDoc) return;
 
1380
        if(!(*exchange2ical->CollaborateDoc)) return;
 
1381
 
 
1382
        ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-COLLABORATEDOC", exchange2ical->CollaborateDoc);
 
1383
}
 
1384
 
 
1385
 
 
1386
void ical_property_X_MS_OLK_CONFCHECK(struct exchange2ical *exchange2ical)
 
1387
{
 
1388
        /* Sanity check */
 
1389
        if (!exchange2ical->ConfCheck) return;
 
1390
        
 
1391
        ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-CONFCHECK", (*exchange2ical->ConfCheck == true) ? "TRUE" : "FALSE");
 
1392
}
 
1393
 
 
1394
 
 
1395
void ical_property_X_MS_OLK_CONFTYPE(struct exchange2ical *exchange2ical)
 
1396
{
 
1397
        char outstr[20];
 
1398
        /* Sanity check */
 
1399
        if (!exchange2ical->ConfType) return;
 
1400
 
 
1401
        snprintf(outstr, 20, "%d", *exchange2ical->ConfType);
 
1402
        ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-CONFTYPE", outstr);
 
1403
}
 
1404
 
 
1405
 
 
1406
void ical_property_X_MS_OLK_DIRECTORY(struct exchange2ical *exchange2ical)
 
1407
{
 
1408
        /*Sanity Check*/
 
1409
        if(!exchange2ical->Directory) return;
 
1410
        if(!(*exchange2ical->Directory)) return;
 
1411
 
 
1412
        ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-DIRECTORY", exchange2ical->Directory);
 
1413
}
 
1414
 
 
1415
 
 
1416
void ical_property_X_MS_OLK_MWSURL(struct exchange2ical *exchange2ical)
 
1417
{
 
1418
        /*Sanity Check*/
 
1419
        if(!exchange2ical->MWSURL) return;
 
1420
 
 
1421
        ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-MWSURL", exchange2ical->MWSURL);
 
1422
}
 
1423
 
 
1424
 
 
1425
void ical_property_X_MS_OLK_NETSHOWURL(struct exchange2ical *exchange2ical)
 
1426
{
 
1427
        /*Sanity Check*/
 
1428
        if(!exchange2ical->NetShowURL) return;
 
1429
        if(!(*exchange2ical->NetShowURL)) return;
 
1430
 
 
1431
        ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-NETSHOWURL", exchange2ical->NetShowURL);
 
1432
}
 
1433
 
 
1434
void ical_property_X_MS_OLK_ONLINEPASSWORD(struct exchange2ical *exchange2ical)
 
1435
{
 
1436
        /*Sanity Check*/
 
1437
        if(!exchange2ical->OnlinePassword) return;
 
1438
        if(!(*exchange2ical->OnlinePassword)) return;
 
1439
 
 
1440
        ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-ONLINEPASSWORD", exchange2ical->OnlinePassword);
 
1441
}
 
1442
 
 
1443
void ical_property_X_MS_OLK_ORGALIAS(struct exchange2ical *exchange2ical)
 
1444
{
 
1445
        /* Sanity check */
 
1446
        if(!exchange2ical->OrgAlias) return;
 
1447
        if(!(*exchange2ical->OrgAlias)) return;
 
1448
 
 
1449
        ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-ORGALIAS", exchange2ical->OrgAlias);
 
1450
}
 
1451
 
 
1452
 
 
1453
// TODO: double check this - need an example.
 
1454
void ical_property_X_MS_OLK_SENDER(struct exchange2ical *exchange2ical)
 
1455
{
 
1456
        icalproperty *prop;
 
1457
        icalparameter *param;
 
1458
        char outstr[200];
 
1459
 
 
1460
        /* Sanity check */
 
1461
        if (!exchange2ical->apptStateFlags) return;
 
1462
        if (!(*exchange2ical->apptStateFlags & 0x1)) return;
 
1463
        if (!exchange2ical->SenderName) return;
 
1464
 
 
1465
        if (exchange2ical->SenderEmailAddress) {
 
1466
                snprintf(outstr, 200, "mailto:%s",exchange2ical->SenderEmailAddress);
 
1467
                prop = icalproperty_new_x(outstr);
 
1468
        } else {
 
1469
                prop = icalproperty_new_x("invalid:nomail");
 
1470
        }
 
1471
 
 
1472
        icalproperty_set_x_name(prop, "X-MS-OLK-SENDER");
 
1473
        icalcomponent_add_property(exchange2ical->vevent, prop);
 
1474
 
 
1475
        param = icalparameter_new_cn(exchange2ical->SenderName);
 
1476
        icalproperty_add_parameter(prop, param);
 
1477
}