Mercurial > libpst
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 } |