comparison 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
comparison
equal deleted inserted replaced
197:07ceebd115ce 198:7c60d6d1c681
516 DEBUG_RET(); 516 DEBUG_RET();
517 return topnode; 517 return topnode;
518 } 518 }
519 519
520 520
521 size_t pst_attach_to_mem(pst_file *pf, pst_item_attach *attach, char **b) { 521 pst_binary pst_attach_to_mem(pst_file *pf, pst_item_attach *attach) {
522 pst_index_ll *ptr; 522 pst_index_ll *ptr;
523 pst_holder h = {b, NULL, 0}; 523 pst_binary rc;
524 size_t size = 0; 524 pst_holder h = {&rc.data, NULL, 0};
525 *b = NULL; 525 rc.size = 0;
526 rc.data = NULL;
526 DEBUG_ENT("pst_attach_to_mem"); 527 DEBUG_ENT("pst_attach_to_mem");
527 if ((!attach->data.data) && (attach->i_id != (uint64_t)-1)) { 528 if ((!attach->data.data) && (attach->i_id != (uint64_t)-1)) {
528 ptr = pst_getID(pf, attach->i_id); 529 ptr = pst_getID(pf, attach->i_id);
529 if (ptr) { 530 if (ptr) {
530 size = pst_ff_getID2data(pf, ptr, &h); 531 rc.size = pst_ff_getID2data(pf, ptr, &h);
531 } else { 532 } else {
532 DEBUG_WARN(("Couldn't find ID pointer. Cannot handle attachment\n")); 533 DEBUG_WARN(("Couldn't find ID pointer. Cannot handle attachment\n"));
533 *b = NULL;
534 } 534 }
535 } else { 535 } else {
536 size = attach->data.size; 536 rc = attach->data;
537 *b = attach->data.data;
538 attach->data.data = NULL; // prevent pst_free_item() from trying to free this 537 attach->data.data = NULL; // prevent pst_free_item() from trying to free this
539 attach->data.size = 0; // since we have given that buffer to the caller 538 attach->data.size = 0; // since we have given that buffer to the caller
540 } 539 }
541 DEBUG_RET(); 540 DEBUG_RET();
542 return size; 541 return rc;
543 } 542 }
544 543
545 544
546 size_t pst_attach_to_file(pst_file *pf, pst_item_attach *attach, FILE* fp) { 545 size_t pst_attach_to_file(pst_file *pf, pst_item_attach *attach, FILE* fp) {
547 pst_index_ll *ptr; 546 pst_index_ll *ptr;
2061 #define LIST_COPY_EMAIL_BIN(label, targ) { \ 2060 #define LIST_COPY_EMAIL_BIN(label, targ) { \
2062 MALLOC_EMAIL(item); \ 2061 MALLOC_EMAIL(item); \
2063 LIST_COPY_BIN(targ); \ 2062 LIST_COPY_BIN(targ); \
2064 DEBUG_EMAIL((label"\n")); \ 2063 DEBUG_EMAIL((label"\n")); \
2065 } 2064 }
2065 #define LIST_COPY_APPT_BIN(label, targ) { \
2066 MALLOC_APPOINTMENT(item); \
2067 LIST_COPY_BIN(targ); \
2068 DEBUG_EMAIL((label"\n")); \
2069 DEBUG_EMAIL_HEXPRINT(targ.data, targ.size); \
2070 }
2066 2071
2067 #define NULL_CHECK(x) { if (!x) { DEBUG_WARN(("NULL_CHECK: Null Found\n")); break;} } 2072 #define NULL_CHECK(x) { if (!x) { DEBUG_WARN(("NULL_CHECK: Null Found\n")); break;} }
2068 2073
2069 2074
2070 /** 2075 /**
2161 item->type = PST_TYPE_REPORT; 2166 item->type = PST_TYPE_REPORT;
2162 else if (pst_strincmp("IPM.Activity", item->ascii_type, 12) == 0) 2167 else if (pst_strincmp("IPM.Activity", item->ascii_type, 12) == 0)
2163 item->type = PST_TYPE_JOURNAL; 2168 item->type = PST_TYPE_JOURNAL;
2164 else if (pst_strincmp("IPM.Appointment", item->ascii_type, 15) == 0) 2169 else if (pst_strincmp("IPM.Appointment", item->ascii_type, 15) == 0)
2165 item->type = PST_TYPE_APPOINTMENT; 2170 item->type = PST_TYPE_APPOINTMENT;
2166 //else if (pst_strincmp("IPM.Schedule.Meeting", item->ascii_type, 20) == 0) 2171 else if (pst_strincmp("IPM.Schedule.Meeting", item->ascii_type, 20) == 0)
2167 // item->type = PST_TYPE_APPOINTMENT; 2172 item->type = PST_TYPE_SCHEDULE; // meeting requests and responses transported over email
2168 // these seem to be appointments, but they are inside the email folder,
2169 // and unless we are in separate mode, we would dump an appointment
2170 // into the middle of a mailbox file.
2171 else if (pst_strincmp("IPM.StickyNote", item->ascii_type, 14) == 0) 2173 else if (pst_strincmp("IPM.StickyNote", item->ascii_type, 14) == 0)
2172 item->type = PST_TYPE_STICKYNOTE; 2174 item->type = PST_TYPE_STICKYNOTE;
2173 else if (pst_strincmp("IPM.Task", item->ascii_type, 8) == 0) 2175 else if (pst_strincmp("IPM.Task", item->ascii_type, 8) == 0)
2174 item->type = PST_TYPE_TASK; 2176 item->type = PST_TYPE_TASK;
2175 else 2177 else
2924 "Phone Call"); 2926 "Phone Call");
2925 break; 2927 break;
2926 case 0x8215: // PR_OUTLOOK_EVENT_ALL_DAY 2928 case 0x8215: // PR_OUTLOOK_EVENT_ALL_DAY
2927 LIST_COPY_APPT_BOOL("All day flag", item->appointment->all_day); 2929 LIST_COPY_APPT_BOOL("All day flag", item->appointment->all_day);
2928 break; 2930 break;
2931 case 0x8216: // PR_OUTLOOK_EVENT_RECURRENCE_DATA
2932 LIST_COPY_APPT_BIN("Appointment recurrence data", item->appointment->recurrence_data);
2933 break;
2934 case 0x8223: // PR_OUTLOOK_EVENT_IS_RECURRING
2935 LIST_COPY_APPT_BOOL("Is recurring", item->appointment->is_recurring);
2936 break;
2929 case 0x8231: // Recurrence type 2937 case 0x8231: // Recurrence type
2930 LIST_COPY_APPT_ENUM("Appointment reccurence", item->appointment->recurrence_type, 0, 5, 2938 LIST_COPY_APPT_ENUM("Appointment recurrence type ", item->appointment->recurrence_type, 0, 5,
2931 "None", 2939 "None",
2932 "Daily", 2940 "Daily",
2933 "Weekly", 2941 "Weekly",
2934 "Monthly", 2942 "Monthly",
2935 "Yearly"); 2943 "Yearly");
2936 break; 2944 break;
2937 case 0x8232: // Recurrence description 2945 case 0x8232: // Recurrence description
2938 LIST_COPY_APPT_STR("Appointment recurrence description", item->appointment->recurrence); 2946 LIST_COPY_APPT_STR("Appointment recurrence description", item->appointment->recurrence_description);
2939 break; 2947 break;
2940 case 0x8234: // TimeZone as String 2948 case 0x8234: // TimeZone as String
2941 LIST_COPY_APPT_STR("TimeZone of times", item->appointment->timezonestring); 2949 LIST_COPY_APPT_STR("TimeZone of times", item->appointment->timezonestring);
2942 break; 2950 break;
2943 case 0x8235: // PR_OUTLOOK_EVENT_RECURRENCE_START 2951 case 0x8235: // PR_OUTLOOK_EVENT_RECURRENCE_START
3331 SAFE_FREE(item->message_store->search_root_folder); 3339 SAFE_FREE(item->message_store->search_root_folder);
3332 SAFE_FREE(item->message_store->top_of_folder); 3340 SAFE_FREE(item->message_store->top_of_folder);
3333 free(item->message_store); 3341 free(item->message_store);
3334 } 3342 }
3335 if (item->contact) { 3343 if (item->contact) {
3336 SAFE_FREE_STR(item->contact->access_method);
3337 SAFE_FREE_STR(item->contact->account_name); 3344 SAFE_FREE_STR(item->contact->account_name);
3338 SAFE_FREE_STR(item->contact->address1); 3345 SAFE_FREE_STR(item->contact->address1);
3339 SAFE_FREE_STR(item->contact->address1a); 3346 SAFE_FREE_STR(item->contact->address1a);
3340 SAFE_FREE_STR(item->contact->address1_desc); 3347 SAFE_FREE_STR(item->contact->address1_desc);
3341 SAFE_FREE_STR(item->contact->address1_transport); 3348 SAFE_FREE_STR(item->contact->address1_transport);
3441 et = item->extra_fields->next; 3448 et = item->extra_fields->next;
3442 free(item->extra_fields); 3449 free(item->extra_fields);
3443 item->extra_fields = et; 3450 item->extra_fields = et;
3444 } 3451 }
3445 if (item->journal) { 3452 if (item->journal) {
3453 SAFE_FREE(item->journal->start);
3446 SAFE_FREE(item->journal->end); 3454 SAFE_FREE(item->journal->end);
3447 SAFE_FREE(item->journal->start);
3448 SAFE_FREE_STR(item->journal->type); 3455 SAFE_FREE_STR(item->journal->type);
3449 free(item->journal); 3456 free(item->journal);
3450 } 3457 }
3451 if (item->appointment) { 3458 if (item->appointment) {
3459 SAFE_FREE(item->appointment->start);
3460 SAFE_FREE(item->appointment->end);
3452 SAFE_FREE_STR(item->appointment->location); 3461 SAFE_FREE_STR(item->appointment->location);
3453 SAFE_FREE(item->appointment->reminder); 3462 SAFE_FREE(item->appointment->reminder);
3454 SAFE_FREE_STR(item->appointment->alarm_filename); 3463 SAFE_FREE_STR(item->appointment->alarm_filename);
3455 SAFE_FREE(item->appointment->start);
3456 SAFE_FREE(item->appointment->end);
3457 SAFE_FREE_STR(item->appointment->timezonestring); 3464 SAFE_FREE_STR(item->appointment->timezonestring);
3458 SAFE_FREE_STR(item->appointment->recurrence); 3465 SAFE_FREE_STR(item->appointment->recurrence_description);
3466 SAFE_FREE_BIN(item->appointment->recurrence_data);
3459 SAFE_FREE(item->appointment->recurrence_start); 3467 SAFE_FREE(item->appointment->recurrence_start);
3460 SAFE_FREE(item->appointment->recurrence_end); 3468 SAFE_FREE(item->appointment->recurrence_end);
3461 free(item->appointment); 3469 free(item->appointment);
3462 } 3470 }
3463 SAFE_FREE(item->ascii_type); 3471 SAFE_FREE(item->ascii_type);
4163 } 4171 }
4164 4172
4165 4173
4166 char *pst_rfc2425_datetime_format(const FILETIME *ft) { 4174 char *pst_rfc2425_datetime_format(const FILETIME *ft) {
4167 static char buffer[30]; 4175 static char buffer[30];
4168 struct tm *stm = NULL; 4176 struct tm* stm = NULL;
4169 DEBUG_ENT("rfc2425_datetime_format"); 4177 DEBUG_ENT("rfc2425_datetime_format");
4170 stm = pst_fileTimeToStructTM(ft); 4178 stm = pst_fileTimeToStructTM(ft);
4171 if (strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%SZ", stm)==0) { 4179 if (strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%SZ", stm)==0) {
4172 DEBUG_INFO(("Problem occured formatting date\n")); 4180 DEBUG_INFO(("Problem occured formatting date\n"));
4173 } 4181 }
4176 } 4184 }
4177 4185
4178 4186
4179 char *pst_rfc2445_datetime_format(const FILETIME *ft) { 4187 char *pst_rfc2445_datetime_format(const FILETIME *ft) {
4180 static char buffer[30]; 4188 static char buffer[30];
4181 struct tm *stm = NULL; 4189 struct tm* stm = NULL;
4182 DEBUG_ENT("rfc2445_datetime_format"); 4190 DEBUG_ENT("rfc2445_datetime_format");
4183 stm = pst_fileTimeToStructTM(ft); 4191 stm = pst_fileTimeToStructTM(ft);
4184 if (strftime(buffer, sizeof(buffer), "%Y%m%dT%H%M%SZ", stm)==0) { 4192 if (strftime(buffer, sizeof(buffer), "%Y%m%dT%H%M%SZ", stm)==0) {
4193 DEBUG_INFO(("Problem occured formatting date\n"));
4194 }
4195 DEBUG_RET();
4196 return buffer;
4197 }
4198
4199
4200 char *pst_rfc2445_datetime_format_now() {
4201 static char buffer[30];
4202 struct tm stm;
4203 time_t t = time(NULL);
4204 DEBUG_ENT("rfc2445_datetime_format_now");
4205 gmtime_r(&t, &stm);
4206 if (strftime(buffer, sizeof(buffer), "%Y%m%dT%H%M%SZ", &stm)==0) {
4185 DEBUG_INFO(("Problem occured formatting date\n")); 4207 DEBUG_INFO(("Problem occured formatting date\n"));
4186 } 4208 }
4187 DEBUG_RET(); 4209 DEBUG_RET();
4188 return buffer; 4210 return buffer;
4189 } 4211 }
4285 str->is_utf8 = 1; 4307 str->is_utf8 = 1;
4286 } 4308 }
4287 free(newer); 4309 free(newer);
4288 DEBUG_RET(); 4310 DEBUG_RET();
4289 } 4311 }
4312
4313
4314 /** Decode raw recurrence data into a better structure.
4315 * @param appt pointer to appointment structure
4316 * @return pointer to decoded recurrence structure that must be free'd by the caller.
4317 */
4318 pst_recurrence* pst_convert_recurrence(pst_item_appointment* appt)
4319 {
4320 int m[4] = {3,4,4,5};
4321 pst_recurrence *r = pst_malloc(sizeof(pst_recurrence));
4322 memset(r, 0, sizeof(pst_recurrence));
4323 size_t s = appt->recurrence_data.size;
4324 size_t i = 0;
4325 char* p = appt->recurrence_data.data;
4326 if (p) {
4327 if (i+4 <= s) { r->signature = PST_LE_GET_UINT32(p+i); i += 4; }
4328 if (i <= s) { r->type = PST_LE_GET_UINT8(p+i) - 0x0a; i += 2; }
4329 if (i+4 <= s) { r->sub_type = PST_LE_GET_UINT32(p+i); i += 4; }
4330 if (r->sub_type <= 3) {
4331 int n = m[r->sub_type];
4332 int j = 0;
4333 for (j=0; j<n; j++) {
4334 if (i+4 <= s) { *(&r->parm1 + j) = PST_LE_GET_UINT32(p+i); i += 4; }
4335 }
4336 }
4337 if (i <= s) { r->termination = PST_LE_GET_UINT8(p+i) - 0x21; i += 4; }
4338 if (i+4 <= s) { r->count = PST_LE_GET_UINT32(p+i); i += 4; }
4339 switch (r->type) {
4340 case 0: // daily
4341 r->interval = r->parm2 / (24 * 60); // was minutes between recurrences
4342 if (r->sub_type) r->interval = 0; // !! don't handle sub-type 1 yet
4343 break;
4344 case 1: // weekly
4345 r->interval = r->parm2;
4346 break;
4347 case 2: // monthly
4348 r->interval = r->parm2;
4349 // two flavors, every month on the Dth day, and every month on the Nth Tuesday
4350 // those are not handled here.
4351 break;
4352 case 3: // yearly
4353 r->interval = 0;
4354 // two flavors, every year on the Dth day of the Mth month, and every year on the Nth Tuesday of the Mth month
4355 // those are not handled here.
4356 break;
4357 default:
4358 break;
4359 }
4360 }
4361 return r;
4362 }
4363
4364
4365 /** Free a recurrence structure.
4366 * @param r input pointer to be freed
4367 */
4368 void pst_free_recurrence(pst_recurrence* r)
4369 {
4370 if (r) free(r);
4371 }