Mercurial > libpst
diff src/libpst.c @ 198:7c60d6d1c681
decode more recurrence mapi elements
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Tue, 12 May 2009 19:34:49 -0700 |
parents | 320cfcba8058 |
children | e3a46f66332b |
line wrap: on
line diff
--- a/src/libpst.c Wed May 06 10:37:46 2009 -0700 +++ b/src/libpst.c Tue May 12 19:34:49 2009 -0700 @@ -518,28 +518,27 @@ } -size_t pst_attach_to_mem(pst_file *pf, pst_item_attach *attach, char **b) { +pst_binary pst_attach_to_mem(pst_file *pf, pst_item_attach *attach) { pst_index_ll *ptr; - pst_holder h = {b, NULL, 0}; - size_t size = 0; - *b = NULL; + pst_binary rc; + pst_holder h = {&rc.data, NULL, 0}; + rc.size = 0; + rc.data = NULL; DEBUG_ENT("pst_attach_to_mem"); if ((!attach->data.data) && (attach->i_id != (uint64_t)-1)) { ptr = pst_getID(pf, attach->i_id); if (ptr) { - size = pst_ff_getID2data(pf, ptr, &h); + rc.size = pst_ff_getID2data(pf, ptr, &h); } else { DEBUG_WARN(("Couldn't find ID pointer. Cannot handle attachment\n")); - *b = NULL; } } else { - size = attach->data.size; - *b = attach->data.data; + rc = attach->data; attach->data.data = NULL; // prevent pst_free_item() from trying to free this attach->data.size = 0; // since we have given that buffer to the caller } DEBUG_RET(); - return size; + return rc; } @@ -2063,6 +2062,12 @@ LIST_COPY_BIN(targ); \ DEBUG_EMAIL((label"\n")); \ } +#define LIST_COPY_APPT_BIN(label, targ) { \ + MALLOC_APPOINTMENT(item); \ + LIST_COPY_BIN(targ); \ + DEBUG_EMAIL((label"\n")); \ + DEBUG_EMAIL_HEXPRINT(targ.data, targ.size); \ +} #define NULL_CHECK(x) { if (!x) { DEBUG_WARN(("NULL_CHECK: Null Found\n")); break;} } @@ -2163,11 +2168,8 @@ item->type = PST_TYPE_JOURNAL; else if (pst_strincmp("IPM.Appointment", item->ascii_type, 15) == 0) item->type = PST_TYPE_APPOINTMENT; - //else if (pst_strincmp("IPM.Schedule.Meeting", item->ascii_type, 20) == 0) - // item->type = PST_TYPE_APPOINTMENT; - // these seem to be appointments, but they are inside the email folder, - // and unless we are in separate mode, we would dump an appointment - // into the middle of a mailbox file. + else if (pst_strincmp("IPM.Schedule.Meeting", item->ascii_type, 20) == 0) + item->type = PST_TYPE_SCHEDULE; // meeting requests and responses transported over email else if (pst_strincmp("IPM.StickyNote", item->ascii_type, 14) == 0) item->type = PST_TYPE_STICKYNOTE; else if (pst_strincmp("IPM.Task", item->ascii_type, 8) == 0) @@ -2926,8 +2928,14 @@ case 0x8215: // PR_OUTLOOK_EVENT_ALL_DAY LIST_COPY_APPT_BOOL("All day flag", item->appointment->all_day); break; + case 0x8216: // PR_OUTLOOK_EVENT_RECURRENCE_DATA + LIST_COPY_APPT_BIN("Appointment recurrence data", item->appointment->recurrence_data); + break; + case 0x8223: // PR_OUTLOOK_EVENT_IS_RECURRING + LIST_COPY_APPT_BOOL("Is recurring", item->appointment->is_recurring); + break; case 0x8231: // Recurrence type - LIST_COPY_APPT_ENUM("Appointment reccurence", item->appointment->recurrence_type, 0, 5, + LIST_COPY_APPT_ENUM("Appointment recurrence type ", item->appointment->recurrence_type, 0, 5, "None", "Daily", "Weekly", @@ -2935,7 +2943,7 @@ "Yearly"); break; case 0x8232: // Recurrence description - LIST_COPY_APPT_STR("Appointment recurrence description", item->appointment->recurrence); + LIST_COPY_APPT_STR("Appointment recurrence description", item->appointment->recurrence_description); break; case 0x8234: // TimeZone as String LIST_COPY_APPT_STR("TimeZone of times", item->appointment->timezonestring); @@ -3333,7 +3341,6 @@ free(item->message_store); } if (item->contact) { - SAFE_FREE_STR(item->contact->access_method); SAFE_FREE_STR(item->contact->account_name); SAFE_FREE_STR(item->contact->address1); SAFE_FREE_STR(item->contact->address1a); @@ -3443,19 +3450,20 @@ item->extra_fields = et; } if (item->journal) { + SAFE_FREE(item->journal->start); SAFE_FREE(item->journal->end); - SAFE_FREE(item->journal->start); SAFE_FREE_STR(item->journal->type); free(item->journal); } if (item->appointment) { + SAFE_FREE(item->appointment->start); + SAFE_FREE(item->appointment->end); SAFE_FREE_STR(item->appointment->location); SAFE_FREE(item->appointment->reminder); SAFE_FREE_STR(item->appointment->alarm_filename); - SAFE_FREE(item->appointment->start); - SAFE_FREE(item->appointment->end); SAFE_FREE_STR(item->appointment->timezonestring); - SAFE_FREE_STR(item->appointment->recurrence); + SAFE_FREE_STR(item->appointment->recurrence_description); + SAFE_FREE_BIN(item->appointment->recurrence_data); SAFE_FREE(item->appointment->recurrence_start); SAFE_FREE(item->appointment->recurrence_end); free(item->appointment); @@ -4165,7 +4173,7 @@ char *pst_rfc2425_datetime_format(const FILETIME *ft) { static char buffer[30]; - struct tm *stm = NULL; + struct tm* stm = NULL; DEBUG_ENT("rfc2425_datetime_format"); stm = pst_fileTimeToStructTM(ft); if (strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%SZ", stm)==0) { @@ -4178,7 +4186,7 @@ char *pst_rfc2445_datetime_format(const FILETIME *ft) { static char buffer[30]; - struct tm *stm = NULL; + struct tm* stm = NULL; DEBUG_ENT("rfc2445_datetime_format"); stm = pst_fileTimeToStructTM(ft); if (strftime(buffer, sizeof(buffer), "%Y%m%dT%H%M%SZ", stm)==0) { @@ -4189,6 +4197,20 @@ } +char *pst_rfc2445_datetime_format_now() { + static char buffer[30]; + struct tm stm; + time_t t = time(NULL); + DEBUG_ENT("rfc2445_datetime_format_now"); + gmtime_r(&t, &stm); + if (strftime(buffer, sizeof(buffer), "%Y%m%dT%H%M%SZ", &stm)==0) { + DEBUG_INFO(("Problem occured formatting date\n")); + } + DEBUG_RET(); + return buffer; +} + + /** Convert a code page integer into a string suitable for iconv() * * @param cp the code page integer used in the pst file @@ -4287,3 +4309,63 @@ free(newer); DEBUG_RET(); } + + +/** Decode raw recurrence data into a better structure. + * @param appt pointer to appointment structure + * @return pointer to decoded recurrence structure that must be free'd by the caller. + */ +pst_recurrence* pst_convert_recurrence(pst_item_appointment* appt) +{ + int m[4] = {3,4,4,5}; + pst_recurrence *r = pst_malloc(sizeof(pst_recurrence)); + memset(r, 0, sizeof(pst_recurrence)); + size_t s = appt->recurrence_data.size; + size_t i = 0; + char* p = appt->recurrence_data.data; + if (p) { + if (i+4 <= s) { r->signature = PST_LE_GET_UINT32(p+i); i += 4; } + if (i <= s) { r->type = PST_LE_GET_UINT8(p+i) - 0x0a; i += 2; } + if (i+4 <= s) { r->sub_type = PST_LE_GET_UINT32(p+i); i += 4; } + if (r->sub_type <= 3) { + int n = m[r->sub_type]; + int j = 0; + for (j=0; j<n; j++) { + if (i+4 <= s) { *(&r->parm1 + j) = PST_LE_GET_UINT32(p+i); i += 4; } + } + } + if (i <= s) { r->termination = PST_LE_GET_UINT8(p+i) - 0x21; i += 4; } + if (i+4 <= s) { r->count = PST_LE_GET_UINT32(p+i); i += 4; } + switch (r->type) { + case 0: // daily + r->interval = r->parm2 / (24 * 60); // was minutes between recurrences + if (r->sub_type) r->interval = 0; // !! don't handle sub-type 1 yet + break; + case 1: // weekly + r->interval = r->parm2; + break; + case 2: // monthly + r->interval = r->parm2; + // two flavors, every month on the Dth day, and every month on the Nth Tuesday + // those are not handled here. + break; + case 3: // yearly + r->interval = 0; + // two flavors, every year on the Dth day of the Mth month, and every year on the Nth Tuesday of the Mth month + // those are not handled here. + break; + default: + break; + } + } + return r; +} + + +/** Free a recurrence structure. + * @param r input pointer to be freed + */ +void pst_free_recurrence(pst_recurrence* r) +{ + if (r) free(r); +}