# HG changeset patch # User Carl Byington # Date 1252621283 25200 # Node ID fe64279df92b7da4296d339b3151c0be96f3c80b # Parent 42b38d65f7e47833205253feeb36183e11d3040e patches from Chris White, Roberto Polli, Justin Greer diff -r 42b38d65f7e4 -r fe64279df92b AUTHORS --- a/AUTHORS Thu Sep 10 13:01:08 2009 -0700 +++ b/AUTHORS Thu Sep 10 15:21:23 2009 -0700 @@ -28,6 +28,8 @@ Emmanuel Andry hggdh bharder + Chris White + Roberto Polli Testing team: diff -r 42b38d65f7e4 -r fe64279df92b ChangeLog --- a/ChangeLog Thu Sep 10 13:01:08 2009 -0700 +++ b/ChangeLog Thu Sep 10 15:21:23 2009 -0700 @@ -1,3 +1,15 @@ +LibPST 0.6.43 (2009-09-10) +=============================== + * patches from Justin Greer. + add code pages 1200 and 1201 to the list for iconv + add support for 0x0201 indirect blocks that point to 0x0101 blocks + add readpst -t option to select output item types + fix (remove) extra new line inside headers + * cleanup base64 encoding to remove duplicate code. + * patch from Chris White to avoid segfault with embedded appointments. + * patch from Roberto Polli to add creation of some Thunderbird specific meta files. + * patch from Justin Greer to ignore b5 tables at offset zero. + LibPST 0.6.42 (2009-09-03) =============================== * patch from Fridrich Strba to build with DJGPP DOS cross-compiler. diff -r 42b38d65f7e4 -r fe64279df92b NEWS --- a/NEWS Thu Sep 10 13:01:08 2009 -0700 +++ b/NEWS Thu Sep 10 15:21:23 2009 -0700 @@ -1,3 +1,4 @@ +0.6.43 2009-09-10 patches from Justin Greer, Chris White, Roberto Polli 0.6.42 2009-09-03 patch from Fridrich Strba to build with DJGPP DOS cross-compiler 0.6.41 2009-06-23 fix ax_python detection - should not use locate command 0.6.40 2009-06-23 fedora 11 has python2.6, remove pdf version of the man pages diff -r 42b38d65f7e4 -r fe64279df92b regression/regression-tests.bash --- a/regression/regression-tests.bash Thu Sep 10 13:01:08 2009 -0700 +++ b/regression/regression-tests.bash Thu Sep 10 15:21:23 2009 -0700 @@ -47,7 +47,7 @@ fn="$2" echo $fn ba=$(basename "$fn" .pst) - jobs="" + jobs="-j 0" [ -n "$val" ] && jobs="-j 0" rm -rf output$n mkdir output$n @@ -67,11 +67,15 @@ rm -rf output* *.err *.log -if [ "$1" == "dii" ]; then +if [ "$1" == "test" ]; then + dopst 19 harris.pst + +elif [ "$1" == "dii" ]; then dodii 1 ams.pst dodii 2 sample_64.pst dodii 3 test.pst dodii 4 big_mail.pst + elif [ "$1" == "ldif" ]; then doldif 1 ams.pst doldif 2 sample_64.pst diff -r 42b38d65f7e4 -r fe64279df92b src/libpst.c --- a/src/libpst.c Thu Sep 10 13:01:08 2009 -0700 +++ b/src/libpst.c Thu Sep 10 15:21:23 2009 -0700 @@ -1260,27 +1260,28 @@ // DSN/MDN reports? DEBUG_INFO(("DSN/MDN processing\n")); list = pst_parse_block(pf, id2_ptr->id->i_id, id2_head); - if (!list) { + if (list) { + for (x=0; x < list->count_objects; x++) { + attach = (pst_item_attach*) pst_malloc(sizeof(pst_item_attach)); + memset(attach, 0, sizeof(pst_item_attach)); + attach->next = item->attach; + item->attach = attach; + } + if (pst_process(list, item, item->attach)) { + DEBUG_WARN(("ERROR pst_process() failed with DSN/MDN attachments\n")); + pst_freeItem(item); + pst_free_list(list); + if (!m_head) pst_free_id2(id2_head); + DEBUG_RET(); + return NULL; + } + pst_free_list(list); + } else { DEBUG_WARN(("ERROR error processing main DSN/MDN record\n")); - if (!m_head) pst_free_id2(id2_head); - DEBUG_RET(); - return item; + // if (!m_head) pst_free_id2(id2_head); + // DEBUG_RET(); + // return item; } - for (x=0; x < list->count_objects; x++) { - attach = (pst_item_attach*) pst_malloc(sizeof(pst_item_attach)); - memset(attach, 0, sizeof(pst_item_attach)); - attach->next = item->attach; - item->attach = attach; - } - if (pst_process(list, item, item->attach)) { - DEBUG_WARN(("ERROR pst_process() failed with DSN/MDN attachments\n")); - pst_freeItem(item); - pst_free_list(list); - if (!m_head) pst_free_id2(id2_head); - DEBUG_RET(); - return NULL; - } - pst_free_list(list); } if ((id2_ptr = pst_getID2(id2_head, (uint64_t)0x671))) { @@ -1592,24 +1593,29 @@ return NULL; } - if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, table_rec.value, &block_offset5)) { - DEBUG_WARN(("internal error (7c.b5.desc offset %#x) in reading block id %#"PRIx64"\n", table_rec.value, block_id)); - freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); - DEBUG_RET(); - return NULL; + if (table_rec.value > 0) { + if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, table_rec.value, &block_offset5)) { + DEBUG_WARN(("internal error (7c.b5.desc offset %#x) in reading block id %#"PRIx64"\n", table_rec.value, block_id)); + freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); + DEBUG_RET(); + return NULL; + } + + // this will give the number of records in this block + num_mapi_objects = (block_offset5.to - block_offset5.from) / (4 + table_rec.ref_type); + + if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, seven_c_blk.ind2_offset, &block_offset6)) { + DEBUG_WARN(("internal error (7c.ind2 offset %#x) in reading block id %#"PRIx64"\n", seven_c_blk.ind2_offset, block_id)); + freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); + DEBUG_RET(); + return NULL; + } + ind2_ptr = block_offset6.from; + ind2_end = block_offset6.to; } - - // this will give the number of records in this block - num_mapi_objects = (block_offset5.to - block_offset5.from) / (4 + table_rec.ref_type); - - if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, seven_c_blk.ind2_offset, &block_offset6)) { - DEBUG_WARN(("internal error (7c.ind2 offset %#x) in reading block id %#"PRIx64"\n", seven_c_blk.ind2_offset, block_id)); - freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); - DEBUG_RET(); - return NULL; + else { + num_mapi_objects = 0; } - ind2_ptr = block_offset6.from; - ind2_end = block_offset6.to; DEBUG_INFO(("7cec block index2 pointer %#x and end %#x\n", ind2_ptr, ind2_end)); } else { diff -r 42b38d65f7e4 -r fe64279df92b src/readpst.c --- a/src/readpst.c Thu Sep 10 13:01:08 2009 -0700 +++ b/src/readpst.c Thu Sep 10 15:21:23 2009 -0700 @@ -118,6 +118,7 @@ // global settings int mode = MODE_NORMAL; int mode_MH = 0; // a submode of MODE_SEPARATE +int mode_thunder = 0; // a submode of MODE_RECURSE int output_mode = OUTPUT_NORMAL; int contact_mode = CMODE_VCARD; int deleted_mode = DMODE_EXCLUDE; @@ -387,7 +388,7 @@ } // command-line option handling - while ((c = getopt(argc, argv, "bc:Dd:hj:kMo:qrSt:Vw"))!= -1) { + while ((c = getopt(argc, argv, "bc:Dd:hj:kMo:qrSt:uVw"))!= -1) { switch (c) { case 'b': save_rtf_body = 0; @@ -435,15 +436,12 @@ break; case 'r': mode = MODE_RECURSE; + mode_thunder = 0; break; case 'S': mode = MODE_SEPARATE; mode_MH = 0; break; - case 'V': - version(); - exit(0); - break; case 't': // email, appointment, contact, other if (!optarg) { @@ -474,6 +472,14 @@ temp++; } break; + case 'u': + mode = MODE_RECURSE; + mode_thunder = 1; + break; + case 'V': + version(); + exit(0); + break; case 'w': overwrite = 1; break; @@ -632,7 +638,6 @@ printf("\t-S\t- Separate. Write emails in the separate format\n"); printf("\t-b\t- Don't save RTF-Body attachments\n"); printf("\t-c[v|l]\t- Set the Contact output mode. -cv = VCard, -cl = EMail list\n"); - printf("\t-t[eajc]\t- Set the output type list. e = email, a = attachment, j = journal, c = contact\n"); printf("\t-d \t- Debug to file. This is a binary log. Use readpstlog to print it\n"); printf("\t-h\t- Help. This screen\n"); printf("\t-j \t- Number of parallel jobs to run\n"); @@ -640,6 +645,8 @@ printf("\t-o \t- Output directory to write files to. CWD is changed *after* opening pst file\n"); printf("\t-q\t- Quiet. Only print error messages\n"); printf("\t-r\t- Recursive. Output in a recursive format\n"); + printf("\t-t[eajc]\t- Set the output type list. e = email, a = attachment, j = journal, c = contact\n"); + printf("\t-u\t- Thunderbird mode. Write two extra .size and .type files\n"); printf("\t-w\t- Overwrite any output mbox files\n"); printf("\n"); printf("Only one of -k -M -r -S should be specified\n"); @@ -959,8 +966,6 @@ { pst_index_ll *ptr; DEBUG_ENT("write_embedded_message"); - fprintf(f_output, "\n--%s\n", boundary); - fprintf(f_output, "Content-Type: %s\n\n", attach->mimetype.str); ptr = pst_getID(pf, attach->i_id); pst_desc_tree d_ptr; @@ -976,8 +981,20 @@ d_ptr.child_tail = NULL; pst_item *item = pst_parse_item(pf, &d_ptr, attach->id2_head); - write_normal_email(f_output, "", item, MODE_NORMAL, 0, pf, 0, extra_mime_headers); - pst_freeItem(item); + // It appears that if the embedded message contains an appointment/ + // calendar item, pst_parse_item returns NULL due to the presence of + // an unexpected reference type of 0x1048, which seems to represent + // an array of GUIDs representing a CLSID. It's likely that this is + // a reference to an internal Outlook COM class. + // Log the skipped item and continue on. + if (!item) { + DEBUG_WARN(("write_embedded_message: pst_parse_item was unable to parse the embedded message in attachment ID %llu", attach->i_id)); + } else { + fprintf(f_output, "\n--%s\n", boundary); + fprintf(f_output, "Content-Type: %s\n\n", attach->mimetype.str); + write_normal_email(f_output, "", item, MODE_NORMAL, 0, pf, 0, extra_mime_headers); + pst_freeItem(item); + } DEBUG_RET(); } @@ -1869,9 +1886,14 @@ DEBUG_ENT("create_enter_dir"); if (mode == MODE_KMAIL) f->name = mk_kmail_dir(item->file_as.str); - else if (mode == MODE_RECURSE) + else if (mode == MODE_RECURSE) { f->name = mk_recurse_dir(item->file_as.str, f->type); - else if (mode == MODE_SEPARATE) { + if (mode_thunder) { + FILE *type_file = fopen(".type", "w"); + fprintf(type_file, "%d\n", item->type); + fclose(type_file); + } + } else if (mode == MODE_SEPARATE) { // do similar stuff to recurse here. mk_separate_dir(item->file_as.str); f->name = (char*) pst_malloc(10); @@ -1944,9 +1966,14 @@ if (mode == MODE_KMAIL) close_kmail_dir(); - else if (mode == MODE_RECURSE) + else if (mode == MODE_RECURSE) { + if (mode_thunder) { + FILE *type_file = fopen(".size", "w"); + fprintf(type_file, "%i %i\n", f->item_count, f->stored_count); + fclose(type_file); + } close_recurse_dir(); - else if (mode == MODE_SEPARATE) + } else if (mode == MODE_SEPARATE) close_separate_dir(); } diff -r 42b38d65f7e4 -r fe64279df92b xml/libpst.in --- a/xml/libpst.in Thu Sep 10 13:01:08 2009 -0700 +++ b/xml/libpst.in Thu Sep 10 15:21:23 2009 -0700 @@ -67,6 +67,7 @@ + pstfile @@ -186,6 +187,13 @@ + -u + + Sets Thunderbird mode, a submode of recursive mode. This causes + two extra .type and .size meta files to be created. + + + -w Overwrite any previous output files. Beware: When used with the -S