comparison src/libpst.c @ 199:e3a46f66332b

more changes in recurrence decoding
author Carl Byington <carl@five-ten-sg.com>
date Wed, 13 May 2009 11:59:55 -0700
parents 7c60d6d1c681
children 3850a3b11745
comparison
equal deleted inserted replaced
198:7c60d6d1c681 199:e3a46f66332b
2012 } 2012 }
2013 2013
2014 // malloc space and copy the item filetime 2014 // malloc space and copy the item filetime
2015 #define LIST_COPY_TIME(label, targ) { \ 2015 #define LIST_COPY_TIME(label, targ) { \
2016 if (list->elements[x]->type != 0x40) { \ 2016 if (list->elements[x]->type != 0x40) { \
2017 DEBUG_WARN(("src not 0x40 for filetime dst\n")); \ 2017 DEBUG_WARN(("src not 0x40 for filetime dst\n")); \
2018 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); \ 2018 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); \
2019 } \ 2019 } \
2020 targ = (FILETIME*) realloc(targ, sizeof(FILETIME)); \ 2020 targ = (FILETIME*) realloc(targ, sizeof(FILETIME)); \
2021 memcpy(targ, list->elements[x]->data, list->elements[x]->size); \ 2021 memcpy(targ, list->elements[x]->data, list->elements[x]->size); \
2022 LE32_CPU(targ->dwLowDateTime); \ 2022 LE32_CPU(targ->dwLowDateTime); \
2023 LE32_CPU(targ->dwHighDateTime); \ 2023 LE32_CPU(targ->dwHighDateTime); \
2024 DEBUG_EMAIL((label" - %s", pst_fileTimeToAscii(targ))); \ 2024 DEBUG_EMAIL((label" - %s", pst_fileTimeToAscii(targ, time_buffer))); \
2025 } 2025 }
2026 2026
2027 #define LIST_COPY_EMAIL_TIME(label, targ) { \ 2027 #define LIST_COPY_EMAIL_TIME(label, targ) { \
2028 MALLOC_EMAIL(item); \ 2028 MALLOC_EMAIL(item); \
2029 LIST_COPY_TIME(label, targ); \ 2029 LIST_COPY_TIME(label, targ); \
2094 return -1; 2094 return -1;
2095 } 2095 }
2096 2096
2097 while (list) { 2097 while (list) {
2098 int32_t x; 2098 int32_t x;
2099 char time_buffer[30];
2099 for (x=0; x<list->count_elements; x++) { 2100 for (x=0; x<list->count_elements; x++) {
2100 int32_t t; 2101 int32_t t;
2101 DEBUG_EMAIL(("#%d - mapi-id: %#x type: %#x length: %#x\n", x, list->elements[x]->mapi_id, list->elements[x]->type, list->elements[x]->size)); 2102 DEBUG_EMAIL(("#%d - mapi-id: %#x type: %#x length: %#x\n", x, list->elements[x]->mapi_id, list->elements[x]->type, list->elements[x]->size));
2102 2103
2103 switch (list->elements[x]->mapi_id) { 2104 switch (list->elements[x]->mapi_id) {
2959 break; 2960 break;
2960 case 0x8503: // PR_OUTLOOK_COMMON_REMINDER_SET 2961 case 0x8503: // PR_OUTLOOK_COMMON_REMINDER_SET
2961 LIST_COPY_APPT_BOOL("Reminder alarm", item->appointment->alarm); 2962 LIST_COPY_APPT_BOOL("Reminder alarm", item->appointment->alarm);
2962 break; 2963 break;
2963 case 0x8516: // Common start 2964 case 0x8516: // Common start
2964 DEBUG_EMAIL(("Common Start Date - %s\n", pst_fileTimeToAscii((FILETIME*)list->elements[x]->data))); 2965 DEBUG_EMAIL(("Common Start Date - %s\n", pst_fileTimeToAscii((FILETIME*)list->elements[x]->data, time_buffer)));
2965 break; 2966 break;
2966 case 0x8517: // Common end 2967 case 0x8517: // Common end
2967 DEBUG_EMAIL(("Common End Date - %s\n", pst_fileTimeToAscii((FILETIME*)list->elements[x]->data))); 2968 DEBUG_EMAIL(("Common End Date - %s\n", pst_fileTimeToAscii((FILETIME*)list->elements[x]->data, time_buffer)));
2968 break; 2969 break;
2969 case 0x851f: // Play reminder sound filename 2970 case 0x851f: // Play reminder sound filename
2970 LIST_COPY_APPT_STR("Appointment reminder sound filename", item->appointment->alarm_filename); 2971 LIST_COPY_APPT_STR("Appointment reminder sound filename", item->appointment->alarm_filename);
2971 break; 2972 break;
2972 case 0x8530: // Followup 2973 case 0x8530: // Followup
3053 list->elements[x]->size)); 3054 list->elements[x]->size));
3054 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); 3055 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
3055 3056
3056 } else if (list->elements[x]->type == (uint32_t)0x0040) { 3057 } else if (list->elements[x]->type == (uint32_t)0x0040) {
3057 DEBUG_WARN(("Unknown type %#x Date = \"%s\"\n", list->elements[x]->mapi_id, 3058 DEBUG_WARN(("Unknown type %#x Date = \"%s\"\n", list->elements[x]->mapi_id,
3058 pst_fileTimeToAscii((FILETIME*)list->elements[x]->data))); 3059 pst_fileTimeToAscii((FILETIME*)list->elements[x]->data, time_buffer)));
3059 3060
3060 } else if (list->elements[x]->type == (uint32_t)0x0048) { 3061 } else if (list->elements[x]->type == (uint32_t)0x0048) {
3061 DEBUG_WARN(("Unknown type %#x OLE GUID [size = %#x]\n", list->elements[x]->mapi_id, 3062 DEBUG_WARN(("Unknown type %#x OLE GUID [size = %#x]\n", list->elements[x]->mapi_id,
3062 list->elements[x]->size)); 3063 list->elements[x]->size));
3063 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); 3064 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
4105 DEBUG_RET(); 4106 DEBUG_RET();
4106 return x; 4107 return x;
4107 } 4108 }
4108 4109
4109 4110
4110 char *pst_rfc2426_escape(char *str) { 4111 char* pst_rfc2426_escape(char *str) {
4111 static char* buf = NULL; 4112 static char* buf = NULL;
4112 static size_t buflen = 0; 4113 static size_t buflen = 0;
4113 char *ret, *a, *b; 4114 char *ret, *a, *b;
4114 size_t x = 0; 4115 size_t x = 0;
4115 int y, z; 4116 int y, z;
4169 } 4170 }
4170 return r; 4171 return r;
4171 } 4172 }
4172 4173
4173 4174
4174 char *pst_rfc2425_datetime_format(const FILETIME *ft) { 4175 char* pst_rfc2425_datetime_format(const FILETIME* ft, int buflen, char* result) {
4175 static char buffer[30]; 4176 struct tm stm;
4176 struct tm* stm = NULL;
4177 DEBUG_ENT("rfc2425_datetime_format"); 4177 DEBUG_ENT("rfc2425_datetime_format");
4178 stm = pst_fileTimeToStructTM(ft); 4178 pst_fileTimeToStructTM(ft, &stm);
4179 if (strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%SZ", stm)==0) { 4179 if (strftime(result, buflen, "%Y-%m-%dT%H:%M:%SZ", &stm)==0) {
4180 DEBUG_INFO(("Problem occured formatting date\n")); 4180 DEBUG_INFO(("Problem occured formatting date\n"));
4181 } 4181 }
4182 DEBUG_RET(); 4182 DEBUG_RET();
4183 return buffer; 4183 return result;
4184 } 4184 }
4185 4185
4186 4186
4187 char *pst_rfc2445_datetime_format(const FILETIME *ft) { 4187 char* pst_rfc2445_datetime_format(const FILETIME* ft, int buflen, char* result) {
4188 static char buffer[30]; 4188 struct tm stm;
4189 struct tm* stm = NULL;
4190 DEBUG_ENT("rfc2445_datetime_format"); 4189 DEBUG_ENT("rfc2445_datetime_format");
4191 stm = pst_fileTimeToStructTM(ft); 4190 pst_fileTimeToStructTM(ft, &stm);
4192 if (strftime(buffer, sizeof(buffer), "%Y%m%dT%H%M%SZ", stm)==0) { 4191 if (strftime(result, buflen, "%Y%m%dT%H%M%SZ", &stm)==0) {
4193 DEBUG_INFO(("Problem occured formatting date\n")); 4192 DEBUG_INFO(("Problem occured formatting date\n"));
4194 } 4193 }
4195 DEBUG_RET(); 4194 DEBUG_RET();
4196 return buffer; 4195 return result;
4197 } 4196 }
4198 4197
4199 4198
4200 char *pst_rfc2445_datetime_format_now() { 4199 char* pst_rfc2445_datetime_format_now(int buflen, char* result) {
4201 static char buffer[30];
4202 struct tm stm; 4200 struct tm stm;
4203 time_t t = time(NULL); 4201 time_t t = time(NULL);
4204 DEBUG_ENT("rfc2445_datetime_format_now"); 4202 DEBUG_ENT("rfc2445_datetime_format_now");
4205 gmtime_r(&t, &stm); 4203 gmtime_r(&t, &stm);
4206 if (strftime(buffer, sizeof(buffer), "%Y%m%dT%H%M%SZ", &stm)==0) { 4204 if (strftime(result, buflen, "%Y%m%dT%H%M%SZ", &stm)==0) {
4207 DEBUG_INFO(("Problem occured formatting date\n")); 4205 DEBUG_INFO(("Problem occured formatting date\n"));
4208 } 4206 }
4209 DEBUG_RET(); 4207 DEBUG_RET();
4210 return buffer; 4208 return result;
4211 } 4209 }
4212 4210
4213 4211
4214 /** Convert a code page integer into a string suitable for iconv() 4212 /** Convert a code page integer into a string suitable for iconv()
4215 * 4213 *
4315 * @param appt pointer to appointment structure 4313 * @param appt pointer to appointment structure
4316 * @return pointer to decoded recurrence structure that must be free'd by the caller. 4314 * @return pointer to decoded recurrence structure that must be free'd by the caller.
4317 */ 4315 */
4318 pst_recurrence* pst_convert_recurrence(pst_item_appointment* appt) 4316 pst_recurrence* pst_convert_recurrence(pst_item_appointment* appt)
4319 { 4317 {
4318 const int bias = 30 * 24 * 60; // minutes in 30 days
4320 int m[4] = {3,4,4,5}; 4319 int m[4] = {3,4,4,5};
4321 pst_recurrence *r = pst_malloc(sizeof(pst_recurrence)); 4320 pst_recurrence *r = pst_malloc(sizeof(pst_recurrence));
4322 memset(r, 0, sizeof(pst_recurrence)); 4321 memset(r, 0, sizeof(pst_recurrence));
4323 size_t s = appt->recurrence_data.size; 4322 size_t s = appt->recurrence_data.size;
4324 size_t i = 0; 4323 size_t i = 0;
4326 if (p) { 4325 if (p) {
4327 if (i+4 <= s) { r->signature = PST_LE_GET_UINT32(p+i); i += 4; } 4326 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; } 4327 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; } 4328 if (i+4 <= s) { r->sub_type = PST_LE_GET_UINT32(p+i); i += 4; }
4330 if (r->sub_type <= 3) { 4329 if (r->sub_type <= 3) {
4331 int n = m[r->sub_type]; 4330 int n = m[r->sub_type]; // number of parms for this sub_type
4332 int j = 0; 4331 int j = 0;
4333 for (j=0; j<n; j++) { 4332 for (j=0; j<n; j++) {
4334 if (i+4 <= s) { *(&r->parm1 + j) = PST_LE_GET_UINT32(p+i); i += 4; } 4333 if (i+4 <= s) { *(&r->parm1 + j) = PST_LE_GET_UINT32(p+i); i += 4; }
4335 } 4334 }
4336 } 4335 }
4337 if (i <= s) { r->termination = PST_LE_GET_UINT8(p+i) - 0x21; i += 4; } 4336 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; } 4337 if (i+4 <= s) { r->count = PST_LE_GET_UINT32(p+i); i += 4; }
4339 switch (r->type) { 4338 switch (r->type) {
4340 case 0: // daily 4339 case 0: // daily
4341 r->interval = r->parm2 / (24 * 60); // was minutes between recurrences 4340 if (r->sub_type == 0) {
4342 if (r->sub_type) r->interval = 0; // !! don't handle sub-type 1 yet 4341 // simple daily
4342 r->interval = r->parm2 / (24 * 60); // was minutes between recurrences
4343 }
4344 else {
4345 // daily every weekday, subset of weekly
4346 r->interval = 1;
4347 r->bydaymask = r->parm4;
4348 }
4343 break; 4349 break;
4344 case 1: // weekly 4350 case 1: // weekly
4345 r->interval = r->parm2; 4351 r->interval = r->parm2;
4352 r->bydaymask = r->parm4;
4346 break; 4353 break;
4347 case 2: // monthly 4354 case 2: // monthly
4348 r->interval = r->parm2; 4355 r->interval = r->parm2;
4349 // two flavors, every month on the Dth day, and every month on the Nth Tuesday 4356 if (r->sub_type == 2) {
4350 // those are not handled here. 4357 // monthly on day d
4358 r->dayofmonth = r->parm4;
4359 }
4360 else {
4361 // monthly on 2nd tuesday
4362 r->bydaymask = r->parm4;
4363 r->position = r->parm5;
4364 }
4351 break; 4365 break;
4352 case 3: // yearly 4366 case 3: // yearly
4353 r->interval = 0; 4367 r->interval = 1;
4354 // two flavors, every year on the Dth day of the Mth month, and every year on the Nth Tuesday of the Mth month 4368 r->monthofyear = ((r->parm1 + bias/2) / bias) + 1;
4355 // those are not handled here. 4369 if (r->sub_type == 2) {
4370 // yearly on day d of month m
4371 r->dayofmonth = r->parm4;
4372 }
4373 else {
4374 // yearly on 2nd tuesday of month m
4375 r->bydaymask = r->parm4;
4376 r->position = r->parm5;
4377 }
4356 break; 4378 break;
4357 default: 4379 default:
4358 break; 4380 break;
4359 } 4381 }
4360 } 4382 }