void ical_property_X_MICROSOFT_CDO_REPLYTIME(struct exchange2ical *exchange2ical) { struct tm *tm; char outstr[200]; /* Sanity check */ if (!exchange2ical->apptReplyTime) return; tm = get_tm_from_FILETIME(exchange2ical->apptReplyTime); if (tm) { strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm); ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-REPLYTIME", outstr); } }
void ical_property_X_MS_OLK_APPTSEQTIME(struct exchange2ical *exchange2ical) { struct tm *tm = NULL; char outstr[200]; /* Sanity check */ if (!exchange2ical->apptSeqTime) return; tm = get_tm_from_FILETIME(exchange2ical->apptSeqTime); if (tm) { strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm); ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-APPTSEQTIME", outstr); } }
void ical_property_X_MICROSOFT_CDO_ATTENDEE_CRITICAL_CHANGE(struct exchange2ical *exchange2ical) { struct tm *tm; char outstr[200]; /* Sanity check */ if (!exchange2ical->AttendeeCriticalChange) return; tm = get_tm_from_FILETIME(exchange2ical->AttendeeCriticalChange); if (tm) { strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm); ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-ATTENDEE-CRITICAL-CHANGE", outstr); } }
icalcomponent * _Exchange2Ical(mapi_object_t *obj_folder, struct exchange2ical_check *exchange2ical_check) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; int ret; struct SRowSet SRowSet; struct SRow aRow; struct SRow aRowT; struct SPropValue *lpProps; struct SPropTagArray *SPropTagArray = NULL; struct exchange2ical exchange2ical; mapi_object_t obj_table; uint32_t count; int i; mem_ctx = talloc_named(mapi_object_get_session(obj_folder), 0, "exchange2ical"); exchange2ical_init(mem_ctx, &exchange2ical); /* Open the contents table */ mapi_object_init(&obj_table); retval = GetContentsTable(obj_folder, &obj_table, 0, &count); if (retval != MAPI_E_SUCCESS){ talloc_free(mem_ctx); return NULL; } OC_DEBUG(0, "MAILBOX (%d appointments)", count); if (count == 0) { talloc_free(mem_ctx); return NULL; } SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_FID, PR_MID); retval = SetColumns(&obj_table, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { mapi_errstr("SetColumns", retval); talloc_free(mem_ctx); return NULL; } while ((retval = QueryRows(&obj_table, count, TBL_ADVANCE, TBL_FORWARD_READ, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows) { count -= SRowSet.cRows; for (i = (SRowSet.cRows-1); i >= 0; i--) { mapi_object_init(&exchange2ical.obj_message); retval = OpenMessage(obj_folder, SRowSet.aRow[i].lpProps[0].value.d, SRowSet.aRow[i].lpProps[1].value.d, &exchange2ical.obj_message, 0); if (retval != MAPI_E_NOT_FOUND) { SPropTagArray = set_SPropTagArray(mem_ctx, 0x30, PidLidGlobalObjectId, PidNameKeywords, PidLidRecurring, PidLidAppointmentRecur, PidLidAppointmentStateFlags, PidLidTimeZoneDescription, PidLidTimeZoneStruct, PidLidContacts, PidLidAppointmentStartWhole, PidLidAppointmentEndWhole, PidLidAppointmentSubType, PidLidOwnerCriticalChange, PidLidLocation, PidLidNonSendableBcc, PidLidAppointmentSequence, PidLidBusyStatus, PidLidIntendedBusyStatus, PidLidAttendeeCriticalChange, PidLidAppointmentReplyTime, PidLidAppointmentNotAllowPropose, PidLidAllowExternalCheck, PidLidAppointmentLastSequence, PidLidAppointmentSequenceTime, PidLidAutoFillLocation, PidLidAutoStartCheck, PidLidCollaborateDoc, PidLidConferencingCheck, PidLidConferencingType, PidLidDirectory, PidLidMeetingWorkspaceUrl, PidLidNetShowUrl, PidLidOnlinePassword, PidLidOrganizerAlias, PidLidReminderSet, PidLidReminderDelta, PidLidResponseStatus, PR_MESSAGE_CLASS_UNICODE, PR_SENSITIVITY, PR_BODY_UNICODE, PR_CREATION_TIME, PR_LAST_MODIFICATION_TIME, PR_IMPORTANCE, PR_RESPONSE_REQUESTED, PR_SUBJECT_UNICODE, PR_OWNER_APPT_ID, PR_SENDER_NAME, PR_SENDER_EMAIL_ADDRESS, PR_MESSAGE_LOCALE_ID ); retval = GetProps(&exchange2ical.obj_message, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval == MAPI_E_SUCCESS) { aRow.ulAdrEntryPad = 0; aRow.cValues = count; aRow.lpProps = lpProps; /*Get Vcal info if first event*/ if(i==(SRowSet.cRows-1)){ ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, VcalFlag); /*TODO: exit nicely*/ ical_component_VCALENDAR(&exchange2ical); } /*Get required properties to check if right event*/ ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, exchange2ical_check->eFlags); /*Check to see if event is acceptable*/ if (!checkEvent(&exchange2ical, exchange2ical_check, get_tm_from_FILETIME(exchange2ical.apptStartWhole))){ continue; } /*Set RecipientTable*/ retval = GetRecipientTable(&exchange2ical.obj_message, &exchange2ical.Recipients.SRowSet, &exchange2ical.Recipients.SPropTagArray); /*Set PR_BODY_HTML for x_alt_desc property*/ SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_BODY_HTML_UNICODE); retval = GetProps(&exchange2ical.obj_message, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval == MAPI_E_SUCCESS) { aRowT.ulAdrEntryPad = 0; aRowT.cValues = count; aRowT.lpProps = lpProps; exchange2ical.bodyHTML = (const char *)octool_get_propval(&aRowT, PR_BODY_HTML_UNICODE); } /*Get rest of properties*/ ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, (exchange2ical_check->eFlags | EntireFlag)); /*add new vevent*/ ical_component_VEVENT(&exchange2ical); /*Exceptions to event*/ if(exchange2ical_check->eFlags != EventFlag){ ret = exchange2ical_exception_from_EmbeddedObj(&exchange2ical, exchange2ical_check); if (ret){ ret=exchange2ical_exception_from_ExceptionInfo(&exchange2ical, exchange2ical_check); } } /*REMOVE once globalobjid is fixed*/ exchange2ical.idx++; MAPIFreeBuffer(lpProps); exchange2ical_reset(&exchange2ical); } } mapi_object_release(&exchange2ical.obj_message); } } icalcomponent *icalendar = exchange2ical.vcalendar; exchange2ical_clear(&exchange2ical); /* Uninitialize MAPI subsystem */ mapi_object_release(&obj_table); talloc_free(mem_ctx); return icalendar; }
static uint8_t exchange2ical_exception_from_EmbeddedObj(struct exchange2ical *exchange2ical, struct exchange2ical_check *exchange2ical_check) { mapi_object_t obj_tb_attach; mapi_object_t obj_attach; struct SRowSet rowset_attach; struct SPropTagArray *SPropTagArray; const uint32_t *attach_num; struct SPropValue *lpProps; enum MAPISTATUS retval; unsigned int i; uint32_t count; struct SRow aRow2; struct SRow aRowT; mapi_object_init(&obj_tb_attach); retval = GetAttachmentTable(&exchange2ical->obj_message, &obj_tb_attach); if (retval != MAPI_E_SUCCESS) { return 1; }else { SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x1, PR_ATTACH_NUM); retval = SetColumns(&obj_tb_attach, SPropTagArray); MAPIFreeBuffer(SPropTagArray); retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, TBL_FORWARD_READ, &rowset_attach); for (i = 0; i < rowset_attach.cRows; i++) { attach_num = (const uint32_t *)find_SPropValue_data(&(rowset_attach.aRow[i]), PR_ATTACH_NUM); retval = OpenAttach(&exchange2ical->obj_message, *attach_num, &obj_attach); if (retval != MAPI_E_SUCCESS) { return 1; }else { SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x3, PR_ATTACH_METHOD, PR_ATTACHMENT_FLAGS, PR_ATTACHMENT_HIDDEN ); lpProps = NULL; retval = GetProps(&obj_attach, 0, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { return 1; }else { aRow2.ulAdrEntryPad = 0; aRow2.cValues = count; aRow2.lpProps = lpProps; uint32_t *attachmentFlags; uint32_t *attachMethod; uint8_t *attachmentHidden; attachmentFlags = (uint32_t *) octool_get_propval(&aRow2, PR_ATTACHMENT_FLAGS); attachMethod = (uint32_t *) octool_get_propval(&aRow2, PR_ATTACH_METHOD); attachmentHidden = (uint8_t *) octool_get_propval(&aRow2, PR_ATTACHMENT_HIDDEN); if(attachmentFlags && (*attachmentFlags & 0x00000002) && (*attachMethod == 0x00000005) && (attachmentHidden && (*attachmentHidden))) { struct exchange2ical exception; exchange2ical_init(exchange2ical->mem_ctx,&exception); mapi_object_init(&exception.obj_message); retval = OpenEmbeddedMessage(&obj_attach, &exception.obj_message, MAPI_READONLY); if (retval != MAPI_E_SUCCESS) { return 1; }else { SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x2d, PidLidFExceptionalBody, PidLidRecurring, PidLidAppointmentRecur, PidLidAppointmentStateFlags, PidLidTimeZoneDescription, PidLidTimeZoneStruct, PidLidAppointmentStartWhole, PidLidAppointmentEndWhole, PidLidAppointmentSubType, PidLidOwnerCriticalChange, PidLidLocation, PidLidExceptionReplaceTime, PidLidNonSendableBcc, PidLidAppointmentSequence, PidLidBusyStatus, PidLidIntendedBusyStatus, PidLidCleanGlobalObjectId, PidLidAttendeeCriticalChange, PidLidAppointmentReplyTime, PidLidAppointmentNotAllowPropose, PidLidAllowExternalCheck, PidLidAppointmentLastSequence, PidLidAppointmentSequenceTime, PidLidAutoFillLocation, PidLidAutoStartCheck, PidLidCollaborateDoc, PidLidConferencingCheck, PidLidConferencingType, PidLidDirectory, PidLidNetShowUrl, PidLidOnlinePassword, PidLidOrganizerAlias, PidLidReminderSet, PidLidReminderDelta, PR_MESSAGE_CLASS_UNICODE, PR_BODY_UNICODE, PR_CREATION_TIME, PR_LAST_MODIFICATION_TIME, PR_IMPORTANCE, PR_RESPONSE_REQUESTED, PR_SUBJECT_UNICODE, PR_OWNER_APPT_ID, PR_SENDER_NAME, PR_SENDER_EMAIL_ADDRESS, PR_MESSAGE_LOCALE_ID ); retval = GetProps(&exception.obj_message, MAPI_UNICODE, SPropTagArray, &lpProps, &count); if (retval == MAPI_E_SUCCESS) { aRow2.ulAdrEntryPad = 0; aRow2.cValues = count; aRow2.lpProps = lpProps; /*Get required properties to check if right event*/ exchange2ical_get_properties(exchange2ical->mem_ctx, &aRow2, &exception, exchange2ical_check->eFlags); /*Check to see if event is acceptable*/ if (!checkEvent(&exception, exchange2ical_check, get_tm_from_FILETIME(exception.apptStartWhole))){ break; } /*Grab Rest of Properties*/ exchange2ical_get_properties(exchange2ical->mem_ctx, &aRow2, &exception, exchange2ical_check->eFlags | EntireFlag); uint8_t *dBody = (uint8_t *) octool_get_propval(&aRow2, PidLidFExceptionalBody); retval = GetRecipientTable(&exception.obj_message, &exception.Recipients.SRowSet, &exception.Recipients.SPropTagArray); /*Check for set subject*/ if (!exception.Subject){ exception.Subject=exchange2ical->Subject; } /*Check for a set apptSubType*/ if (!exception.apptSubType){ exception.apptSubType=exchange2ical->apptSubType; } /*check for a set Location*/ if (!exception.Location){ exception.Location=exchange2ical->Location; } /*check for set valarm info*/ if(!exception.ReminderSet){ exception.ReminderSet=exchange2ical->ReminderSet; } if(!exception.ReminderDelta){ exception.ReminderDelta=exchange2ical->ReminderDelta; } /*Set to same vcalendar as parent*/ exception.vcalendar=exchange2ical->vcalendar; /*Set to same uid fallback in case GlobalObjId is missing*/ exception.idx=exchange2ical->idx; /*has a modified summary*/ if(dBody && *dBody){ SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x1, PR_BODY_HTML_UNICODE); retval = GetProps(&exception.obj_message, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval == MAPI_E_SUCCESS) { aRowT.ulAdrEntryPad = 0; aRowT.cValues = count; aRowT.lpProps = lpProps; exception.bodyHTML = (const char *)octool_get_propval(&aRowT, PR_BODY_HTML_UNICODE); } /* has the same summary as parent*/ } else{ exception.body=exchange2ical->body; exception.bodyHTML=exchange2ical->bodyHTML; } ical_component_VEVENT(&exception); exception.vcalendar=NULL; exchange2ical_clear(&exception); } } mapi_object_release(&exception.obj_message); } MAPIFreeBuffer(lpProps); } } } } mapi_object_release(&obj_tb_attach); return 0; }