# HG changeset patch # User Carl Byington # Date 1237440678 25200 # Node ID 40e9de4450387f9a9da22e4c80f127c754542291 # Parent 55d4f17a35f215be4c3888c1f99db023a86971a7 improve consistency checking when fetching items from the pst file. avoid putting mixed item types into the same output folder. diff -r 55d4f17a35f2 -r 40e9de445038 ChangeLog --- a/ChangeLog Tue Mar 17 12:14:43 2009 -0700 +++ b/ChangeLog Wed Mar 18 22:31:18 2009 -0700 @@ -1,3 +1,8 @@ +LibPST 0.6.34 (2009-0x-xx) +=============================== + * improve consistency checking when fetching items from the pst file. + * avoid putting mixed item types into the same output folder. + LibPST 0.6.33 (2009-03-17) =============================== diff -r 55d4f17a35f2 -r 40e9de445038 configure.in --- a/configure.in Tue Mar 17 12:14:43 2009 -0700 +++ b/configure.in Wed Mar 18 22:31:18 2009 -0700 @@ -1,5 +1,5 @@ AC_PREREQ(2.59) -AC_INIT(libpst,0.6.33,carl@five-ten-sg.com) +AC_INIT(libpst,0.6.34,carl@five-ten-sg.com) AC_CONFIG_SRCDIR([src/libpst.c]) AC_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE diff -r 55d4f17a35f2 -r 40e9de445038 regression/regression-tests.bash --- a/regression/regression-tests.bash Tue Mar 17 12:14:43 2009 -0700 +++ b/regression/regression-tests.bash Wed Mar 18 22:31:18 2009 -0700 @@ -38,7 +38,7 @@ mkdir output$n # ../src/readpst -cv -o output$n $fn >$ba.err 2>&1 # readpst -cv -o output$n -d dumper $fn >$ba.err 2>&1 - $val ../src/readpst -S -cv -o output$n -d dumper $fn >$ba.err 2>&1 + $val ../src/readpst -r -D -cv -o output$n -d dumper $fn >$ba.err 2>&1 ../src/readpstlog -f I dumper >$ba.log #../src/getidblock -d -p $fn 0 >$ba.fulldump @@ -50,7 +50,7 @@ val="valgrind --leak-check=full" -val='' +#val='' pushd .. make || exit @@ -84,7 +84,7 @@ #doldif 18 test-mac.pst #doldif 19 harris.pst else - dopst 20 spam.pst + dopst 11 flow.pst exit dopst 1 ams.pst dopst 2 sample_64.pst @@ -96,7 +96,6 @@ dopst 8 ol2k3high.pst dopst 9 ol97high.pst dopst 10 returned_message.pst - dopst 11 flow.pst dopst 12 test-html.pst dopst 13 test-text.pst dopst 14 joe.romanowski.pst @@ -105,6 +104,8 @@ #dopst 17 hourig3.pst dopst 18 test-mac.pst dopst 19 harris.pst + dopst 20 spam.pst fi grep 'lost:' *err | grep -v 'lost: 0 ' +grep 'should have been' *err diff -r 55d4f17a35f2 -r 40e9de445038 src/Makefile.am --- a/src/Makefile.am Tue Mar 17 12:14:43 2009 -0700 +++ b/src/Makefile.am Wed Mar 18 22:31:18 2009 -0700 @@ -74,7 +74,7 @@ libstrfunc.h\ timeconv.h \ vbuf.h - libpst_la_LDFLAGS = $(NO_UNDEFINED) -version-info 1:2:0 + libpst_la_LDFLAGS = $(NO_UNDEFINED) -version-info 1:3:0 endif libpst_la_SOURCES = $(common_source) $(common_header) diff -r 55d4f17a35f2 -r 40e9de445038 src/libpst.c --- a/src/libpst.c Tue Mar 17 12:14:43 2009 -0700 +++ b/src/libpst.c Wed Mar 18 22:31:18 2009 -0700 @@ -417,9 +417,9 @@ DEBUG_WARN(("Couldn't find ID pointer. Cannot handle attachment\n")); size = 0; } - attach->size = size; + attach->data.size = size; } else { - size = attach->size; + size = attach->data.size; } DEBUG_RET(); return size; @@ -438,11 +438,11 @@ } else { DEBUG_WARN(("Couldn't find ID pointer. Cannot save attachment to file\n")); } - attach->size = size; + attach->data.size = size; } else { // save the attachment to the file - size = attach->size; - (void)pst_fwrite(attach->data, (size_t)1, size, fp); + size = attach->data.size; + (void)pst_fwrite(attach->data.data, (size_t)1, size, fp); } DEBUG_RET(); return size; @@ -461,15 +461,15 @@ } else { DEBUG_WARN(("Couldn't find ID pointer. Cannot save attachment to Base64\n")); } - attach->size = size; + attach->data.size = size; } else { // encode the attachment to the file - char *c = base64_encode(attach->data, attach->size); + char *c = base64_encode(attach->data.data, attach->data.size); if (c) { (void)pst_fwrite(c, (size_t)1, strlen(c), fp); free(c); // caught by valgrind } - size = attach->size; + size = attach->data.size; } DEBUG_RET(); return size; @@ -1711,6 +1711,7 @@ // This version of free does NULL check first #define SAFE_FREE(x) {if (x) free(x);} #define SAFE_FREE_STR(x) SAFE_FREE(x.str) +#define SAFE_FREE_BIN(x) SAFE_FREE(x.data) // check if item->email is NULL, and init if so #define MALLOC_EMAIL(x) { if (!x->email) { x->email = (pst_item_email*) xmalloc(sizeof(pst_item_email)); memset(x->email, 0, sizeof(pst_item_email) );} } @@ -1721,20 +1722,38 @@ #define MALLOC_APPOINTMENT(x) { if (!x->appointment) { x->appointment = (pst_item_appointment*) xmalloc(sizeof(pst_item_appointment)); memset(x->appointment, 0, sizeof(pst_item_appointment) );} } // malloc space and copy the current item's data null terminated -#define LIST_COPY(targ, type) { \ +#define LIST_COPY(targ, type) { \ targ = type realloc(targ, list->elements[x]->size+1); \ - memcpy(targ, list->elements[x]->data, list->elements[x]->size); \ + memcpy(targ, list->elements[x]->data, list->elements[x]->size);\ memset(((char*)targ)+list->elements[x]->size, 0, (size_t)1); \ } -#define LIST_COPY_BOOL(label, targ) { \ - if (*(int16_t*)list->elements[x]->data) { \ - DEBUG_EMAIL((label" - True\n")); \ - targ = 1; \ - } else { \ - DEBUG_EMAIL((label" - False\n")); \ - targ = 0; \ - } \ +#define LIST_COPY_CSTR(targ) { \ + if ((list->elements[x]->type == 0x1f) || \ + (list->elements[x]->type == 0x1e) || \ + (list->elements[x]->type == 0x102)) { \ + LIST_COPY(targ, (char*)) \ + } \ + else { \ + DEBUG_EMAIL(("src not 0x1e or 0x1f or 0x102 for string dst\n")); \ + DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); \ + SAFE_FREE(targ); \ + targ = NULL; \ + } \ +} + +#define LIST_COPY_BOOL(label, targ) { \ + if (list->elements[x]->type != 0x0b) { \ + DEBUG_EMAIL(("src not 0x0b for boolean dst\n")); \ + DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); \ + } \ + if (*(int16_t*)list->elements[x]->data) { \ + DEBUG_EMAIL((label" - True\n")); \ + targ = 1; \ + } else { \ + DEBUG_EMAIL((label" - False\n")); \ + targ = 0; \ + } \ } #define LIST_COPY_EMAIL_BOOL(label, targ) { \ @@ -1752,23 +1771,31 @@ LIST_COPY_BOOL(label, targ) \ } -#define LIST_COPY_INT16_N(label, targ) { \ - memcpy(&(targ), list->elements[x]->data, sizeof(targ)); \ - LE16_CPU(targ); \ +#define LIST_COPY_INT16_N(targ) { \ + if (list->elements[x]->type != 0x02) { \ + DEBUG_EMAIL(("src not 0x02 for int16 dst\n")); \ + DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); \ + } \ + memcpy(&(targ), list->elements[x]->data, sizeof(targ)); \ + LE16_CPU(targ); \ } #define LIST_COPY_INT16(label, targ) { \ - LIST_COPY_INT16_N(label, targ); \ + LIST_COPY_INT16_N(targ); \ DEBUG_EMAIL((label" - %i %#x\n", (int)targ, (int)targ)); \ } -#define LIST_COPY_INT32_N(label, targ) { \ - memcpy(&(targ), list->elements[x]->data, sizeof(targ)); \ - LE32_CPU(targ); \ +#define LIST_COPY_INT32_N(targ) { \ + if (list->elements[x]->type != 0x03) { \ + DEBUG_EMAIL(("src not 0x03 for int32 dst\n")); \ + DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); \ + } \ + memcpy(&(targ), list->elements[x]->data, sizeof(targ)); \ + LE32_CPU(targ); \ } #define LIST_COPY_INT32(label, targ) { \ - LIST_COPY_INT32_N(label, targ); \ + LIST_COPY_INT32_N(targ); \ DEBUG_EMAIL((label" - %i %#x\n", (int)targ, (int)targ)); \ } @@ -1794,7 +1821,7 @@ #define LIST_COPY_ENUM(label, targ, delta, count, ...) { \ char *tlabels[] = {__VA_ARGS__}; \ - LIST_COPY_INT32_N(label, targ); \ + LIST_COPY_INT32_N(targ); \ targ += delta; \ DEBUG_EMAIL((label" - %s [%i]\n", \ (((int)targ < 0) || ((int)targ >= count)) \ @@ -1814,7 +1841,7 @@ #define LIST_COPY_ENUM16(label, targ, delta, count, ...) { \ char *tlabels[] = {__VA_ARGS__}; \ - LIST_COPY_INT16_N(label, targ); \ + LIST_COPY_INT16_N(targ); \ targ += delta; \ DEBUG_EMAIL((label" - %s [%i]\n", \ (((int)targ < 0) || ((int)targ >= count)) \ @@ -1828,7 +1855,6 @@ } #define LIST_COPY_ENTRYID(label, targ) { \ - MALLOC_MESSAGESTORE(item); \ LIST_COPY(targ, (pst_entryid*)); \ LE32_CPU(targ->u1); \ LE32_CPU(targ->id); \ @@ -1849,8 +1875,8 @@ // malloc space and copy the current item's data null terminated // including the utf8 flag #define LIST_COPY_STR(label, targ) { \ - LIST_COPY(targ.str, (char*)); \ - targ.is_utf8 = (list->elements[x]->type == 0x1f) ? 1 : 0; \ + LIST_COPY_CSTR(targ.str); \ + targ.is_utf8 = (list->elements[x]->type == 0x1f) ? 1 : 0; \ DEBUG_EMAIL((label" - unicode %d - %s\n", targ.is_utf8, targ.str)); \ } @@ -1875,12 +1901,16 @@ } // malloc space and copy the item filetime -#define LIST_COPY_TIME(label, targ) { \ - targ = (FILETIME*) realloc(targ, sizeof(FILETIME)); \ - memcpy(targ, list->elements[x]->data, list->elements[x]->size); \ - LE32_CPU(targ->dwLowDateTime); \ - LE32_CPU(targ->dwHighDateTime); \ - DEBUG_EMAIL((label" - %s", fileTimeToAscii(targ))); \ +#define LIST_COPY_TIME(label, targ) { \ + if (list->elements[x]->type != 0x40) { \ + DEBUG_EMAIL(("src not 0x40 for filetime dst\n")); \ + DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); \ + } \ + targ = (FILETIME*) realloc(targ, sizeof(FILETIME)); \ + memcpy(targ, list->elements[x]->data, list->elements[x]->size); \ + LE32_CPU(targ->dwLowDateTime); \ + LE32_CPU(targ->dwHighDateTime); \ + DEBUG_EMAIL((label" - %s", fileTimeToAscii(targ))); \ } #define LIST_COPY_EMAIL_TIME(label, targ) { \ @@ -1904,21 +1934,21 @@ } // malloc space and copy the current item's data and size -#define LIST_COPY_SIZE(targ, type, mysize) { \ - mysize = list->elements[x]->size; \ - if (mysize) { \ - targ = type realloc(targ, mysize); \ - memcpy(targ, list->elements[x]->data, mysize); \ - } \ - else { \ - SAFE_FREE(targ); \ - targ = NULL; \ - } \ +#define LIST_COPY_BIN(targ) { \ + targ.size = list->elements[x]->size; \ + if (targ.size) { \ + targ.data = (char*)realloc(targ.data, targ.size); \ + memcpy(targ.data, list->elements[x]->data, targ.size); \ + } \ + else { \ + SAFE_FREE_BIN(targ); \ + targ.data = NULL; \ + } \ } -#define LIST_COPY_EMAIL_SIZE(label, targ, mysize) { \ +#define LIST_COPY_EMAIL_BIN(label, targ) { \ MALLOC_EMAIL(item); \ - LIST_COPY_SIZE(targ, (char*), mysize); \ + LIST_COPY_BIN(targ); \ DEBUG_EMAIL((label"\n")); \ } @@ -1957,12 +1987,14 @@ switch (list->elements[x]->mapi_id) { case PST_ATTRIB_HEADER: // CUSTOM attribute for saying the Extra Headers - if (list->elements[x]->extra) { + if ((list->elements[x]->extra) && + ((list->elements[x]->type == 0x1f) || + (list->elements[x]->type == 0x1e))) { ef = (pst_item_extra_field*) xmalloc(sizeof(pst_item_extra_field)); memset(ef, 0, sizeof(pst_item_extra_field)); ef->field_name = (char*) xmalloc(strlen(list->elements[x]->extra)+1); strcpy(ef->field_name, list->elements[x]->extra); - LIST_COPY(ef->value, (char*)); + LIST_COPY_CSTR(ef->value); ef->next = item->extra_fields; item->extra_fields = ef; DEBUG_EMAIL(("Extra Field - \"%s\" = \"%s\"\n", ef->field_name, ef->value)); @@ -1984,13 +2016,19 @@ } } else { - DEBUG_EMAIL(("NULL extra field\n")); + DEBUG_EMAIL(("What does this mean?\n")); + DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); } break; case 0x0002: // PR_ALTERNATE_RECIPIENT_ALLOWED - // If set to true, the sender allows this email to be autoforwarded - LIST_COPY_EMAIL_BOOL("AutoForward allowed", item->email->autoforward); - if (!item->email->autoforward) item->email->autoforward = -1; + if (list->elements[x]->type == 0x0b) { + // If set to true, the sender allows this email to be autoforwarded + LIST_COPY_EMAIL_BOOL("AutoForward allowed", item->email->autoforward); + if (!item->email->autoforward) item->email->autoforward = -1; + } else { + DEBUG_EMAIL(("What does this mean?\n")); + DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); + } break; case 0x0003: // Extended Attributes table DEBUG_EMAIL(("Extended Attributes Table - NOT PROCESSED\n")); @@ -1999,28 +2037,49 @@ LIST_COPY_EMAIL_ENUM("Importance Level", item->email->importance, 0, 3, "Low", "Normal", "High"); break; case 0x001A: // PR_MESSAGE_CLASS IPM.x - LIST_COPY(item->ascii_type, (char*)); - if (pst_strincmp("IPM.Note", item->ascii_type, 8) == 0) - item->type = PST_TYPE_NOTE; - else if (pst_stricmp("IPM", item->ascii_type) == 0) - item->type = PST_TYPE_NOTE; - else if (pst_strincmp("IPM.Contact", item->ascii_type, 11) == 0) - item->type = PST_TYPE_CONTACT; - else if (pst_strincmp("REPORT.IPM.Note", item->ascii_type, 15) == 0) - item->type = PST_TYPE_REPORT; - else if (pst_strincmp("IPM.Activity", item->ascii_type, 12) == 0) - 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.Task", item->ascii_type, 8) == 0) - item->type = PST_TYPE_TASK; - else - item->type = PST_TYPE_OTHER; - DEBUG_EMAIL(("Message class %s [%"PRIi32"] \n", item->ascii_type, item->type)); + if ((list->elements[x]->type == 0x1e) || + (list->elements[x]->type == 0x1e)) { + LIST_COPY_CSTR(item->ascii_type); + if (!item->ascii_type) item->ascii_type = strdup("unknown"); + if (pst_strincmp("IPM.Note", item->ascii_type, 8) == 0) + item->type = PST_TYPE_NOTE; + else if (pst_stricmp("IPM", item->ascii_type) == 0) + item->type = PST_TYPE_NOTE; + else if (pst_strincmp("IPM.Contact", item->ascii_type, 11) == 0) + item->type = PST_TYPE_CONTACT; + else if (pst_strincmp("REPORT.IPM.Note", item->ascii_type, 15) == 0) + item->type = PST_TYPE_REPORT; + else if (pst_strincmp("IPM.Activity", item->ascii_type, 12) == 0) + 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.StickyNote", item->ascii_type, 14) == 0) + item->type = PST_TYPE_STICKYNOTE; + else if (pst_strincmp("IPM.Task", item->ascii_type, 8) == 0) + item->type = PST_TYPE_TASK; + else + item->type = PST_TYPE_OTHER; + DEBUG_EMAIL(("Message class %s [%"PRIi32"] \n", item->ascii_type, item->type)); + } + else { + DEBUG_EMAIL(("What does this mean?\n")); + DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); + } break; case 0x0023: // PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED - // set if the sender wants a delivery report from all recipients - LIST_COPY_EMAIL_BOOL("Global Delivery Report", item->email->delivery_report); + if (list->elements[x]->type == 0x0b) { + // set if the sender wants a delivery report from all recipients + LIST_COPY_EMAIL_BOOL("Global Delivery Report", item->email->delivery_report); + } + else { + DEBUG_EMAIL(("What does this mean?\n")); + DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); + } break; case 0x0026: // PR_PRIORITY LIST_COPY_EMAIL_ENUM("Priority", item->email->priority, 1, 3, "NonUrgent", "Normal", "Urgent"); @@ -2116,7 +2175,7 @@ LIST_COPY_EMAIL_STR("Processed Subject (Conversation Topic)", item->email->processed_subject); break; case 0x0071: // PR_CONVERSATION_INDEX - LIST_COPY_EMAIL_INT32("Conversation Index", item->email->conversation_index); + LIST_COPY_EMAIL_BIN("Conversation Index", item->email->conversation_index); break; case 0x0072: // PR_ORIGINAL_DISPLAY_BCC LIST_COPY_EMAIL_STR("Original display bcc", item->email->original_bcc); @@ -2208,17 +2267,14 @@ LIST_COPY_EMAIL_BOOL("Compressed RTF in Sync", item->email->rtf_in_sync); break; case 0x0E20: // PR_ATTACH_SIZE binary Attachment data in record - DEBUG_EMAIL(("Attachment Size - ")); NULL_CHECK(attach); LIST_COPY_INT32("Attachment Size", t); - attach->size = (size_t)t; + attach->data.size = (size_t)t; break; case 0x0FF9: // PR_RECORD_KEY Record Header 1 - DEBUG_EMAIL(("Record Key 1 - ")); - LIST_COPY(item->record_key, (char*)); - item->record_key_size = list->elements[x]->size; - DEBUG_EMAIL_HEXPRINT(item->record_key, item->record_key_size); - DEBUG_EMAIL(("\n")); + LIST_COPY_BIN(item->record_key); + DEBUG_EMAIL(("Record Key\n")); + DEBUG_EMAIL_HEXPRINT(item->record_key.data, item->record_key.size); break; case 0x1000: // PR_BODY LIST_COPY_STR("Plain Text body", item->body); @@ -2240,7 +2296,7 @@ LIST_COPY_EMAIL_STR("RTF Sync body tag", item->email->rtf_body_tag); break; case 0x1009: // PR_RTF_COMPRESSED - rtf data is lzw compressed - LIST_COPY_EMAIL_SIZE("RTF Compressed body", item->email->rtf_compressed, item->email->rtf_compressed_size); + LIST_COPY_EMAIL_BIN("RTF Compressed body", item->email->rtf_compressed); break; case 0x1010: // PR_RTF_SYNC_PREFIX_COUNT // a count of the ignored characters before the first significant character @@ -2308,17 +2364,17 @@ LIST_COPY_STORE_ENTRYID("Search Root Folder record", item->message_store->search_root_folder); break; case 0x3602: // PR_CONTENT_COUNT Number of emails stored in a folder - LIST_COPY_FOLDER_INT32("Folder Email Count", item->folder->email_count); + LIST_COPY_FOLDER_INT32("Folder Email Count", item->folder->item_count); break; case 0x3603: // PR_CONTENT_UNREAD Number of unread emails - LIST_COPY_FOLDER_INT32("Unread Email Count", item->folder->unseen_email_count); + LIST_COPY_FOLDER_INT32("Unread Email Count", item->folder->unseen_item_count); break; case 0x360A: // PR_SUBFOLDERS Has children MALLOC_FOLDER(item); LIST_COPY_BOOL("Has Subfolders", item->folder->subfolder); break; case 0x3613: // PR_CONTAINER_CLASS IPF.x - LIST_COPY(item->ascii_type, (char*)); + LIST_COPY_CSTR(item->ascii_type); if (pst_strincmp("IPF.Note", item->ascii_type, 8) == 0) item->type = PST_TYPE_NOTE; else if (pst_stricmp("IPF", item->ascii_type) == 0) @@ -2348,12 +2404,9 @@ NULL_CHECK(attach); if (!list->elements[x]->data) { //special case attach->id2_val = list->elements[x]->type; - DEBUG_EMAIL(("Seen a Reference. The data hasn't been loaded yet. [%#"PRIx64"][%#x]\n", - attach->id2_val, list->elements[x]->type)); + DEBUG_EMAIL(("Seen a Reference. The data hasn't been loaded yet. [%#"PRIx64"]\n", attach->id2_val)); } else { - LIST_COPY(attach->data, (char*)); - attach->size = list->elements[x]->size; - DEBUG_EMAIL(("NOT PRINTED\n")); + LIST_COPY_BIN(attach->data); } break; case 0x3704: // PR_ATTACH_FILENAME Attachment filename (8.3) @@ -2635,13 +2688,10 @@ case 0x3FFD: // PR_MESSAGE_CODEPAGE LIST_COPY_INT32("Message code page", item->message_codepage); break; - case 0x65E3: // Entry ID? - DEBUG_EMAIL(("Entry ID - ")); - item->record_key = (char*) xmalloc(16+1); - memcpy(item->record_key, &(list->elements[x]->data[1]), 16); //skip first byte - item->record_key[16]='\0'; - item->record_key_size=16; - DEBUG_EMAIL_HEXPRINT((char*)item->record_key, 16); + case 0x65E3: // PR_PREDECESSOR_CHANGE_LIST + LIST_COPY_BIN(item->predecessor_change); + DEBUG_EMAIL(("Predecessor Change\n")); + DEBUG_EMAIL_HEXPRINT(item->predecessor_change.data, item->predecessor_change.size); break; case 0x67F2: // ID2 value of the attachments proper record DEBUG_EMAIL(("Attachment ID2 value - ")); @@ -2659,13 +2709,13 @@ LIST_COPY_STORE_INT32("Password checksum", item->message_store->pwd_chksum); break; case 0x6F02: // Secure HTML Body - LIST_COPY_EMAIL_SIZE("Secure HTML Body", item->email->encrypted_htmlbody, item->email->encrypted_htmlbody_size); + LIST_COPY_EMAIL_BIN("Secure HTML Body", item->email->encrypted_htmlbody); break; case 0x6F04: // Secure Text Body - LIST_COPY_EMAIL_SIZE("Secure Text Body", item->email->encrypted_body, item->email->encrypted_body_size); + LIST_COPY_EMAIL_BIN("Secure Text Body", item->email->encrypted_body); break; case 0x7C07: // top of folders ENTRYID - LIST_COPY_ENTRYID("Top of folders RecID", item->message_store->top_of_folder); + LIST_COPY_STORE_ENTRYID("Top of folders RecID", item->message_store->top_of_folder); break; case 0x8005: // Contact's Fullname LIST_COPY_CONTACT_STR("Contact Fullname", item->contact->fullname); @@ -2909,12 +2959,12 @@ list->elements[x]->size)); DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); - } else if (list->elements[x]->type == (uint32_t)0x101E) { + } else if (list->elements[x]->type == (uint32_t)0x101e) { DEBUG_EMAIL(("Unknown type %#x Array of Strings [size = %#x]\n", list->elements[x]->mapi_id, list->elements[x]->size)); DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); - } else if (list->elements[x]->type == (uint32_t)0x101F) { + } else if (list->elements[x]->type == (uint32_t)0x101f) { DEBUG_EMAIL(("Unknown type %#x Array of Unicode Strings [size = %#x]\n", list->elements[x]->mapi_id, list->elements[x]->size)); DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); @@ -3103,7 +3153,7 @@ SAFE_FREE_STR(attach->filename1); SAFE_FREE_STR(attach->filename2); SAFE_FREE_STR(attach->mimetype); - SAFE_FREE(attach->data); + SAFE_FREE_BIN(attach->data); pst_free_id2(attach->id2_head); t = attach->next; free(attach); @@ -3121,8 +3171,9 @@ SAFE_FREE(item->email->arrival_date); SAFE_FREE_STR(item->email->cc_address); SAFE_FREE_STR(item->email->bcc_address); - SAFE_FREE(item->email->encrypted_body); - SAFE_FREE(item->email->encrypted_htmlbody); + SAFE_FREE_BIN(item->email->conversation_index); + SAFE_FREE_BIN(item->email->encrypted_body); + SAFE_FREE_BIN(item->email->encrypted_htmlbody); SAFE_FREE_STR(item->email->header); SAFE_FREE_STR(item->email->htmlbody); SAFE_FREE_STR(item->email->in_reply_to); @@ -3143,7 +3194,7 @@ SAFE_FREE_STR(item->email->recip2_address); SAFE_FREE_STR(item->email->reply_to); SAFE_FREE_STR(item->email->rtf_body_tag); - SAFE_FREE(item->email->rtf_compressed); + SAFE_FREE_BIN(item->email->rtf_compressed); SAFE_FREE_STR(item->email->return_path_address); SAFE_FREE_STR(item->email->sender_access); SAFE_FREE_STR(item->email->sender_address); @@ -3308,7 +3359,8 @@ SAFE_FREE_STR(item->file_as); SAFE_FREE(item->modify_date); SAFE_FREE_STR(item->outlook_version); - SAFE_FREE(item->record_key); + SAFE_FREE_BIN(item->record_key); + SAFE_FREE_BIN(item->predecessor_change); free(item); } DEBUG_RET(); @@ -3784,7 +3836,7 @@ DEBUG_RET(); return 0; } - DEBUG_HEXDUMPC(buf3, a, 0x10); + DEBUG_HEXDUMPC(buf3, a, 16); memcpy(&block_hdr, buf3, sizeof(block_hdr)); LE16_CPU(block_hdr.index_offset); LE16_CPU(block_hdr.type); diff -r 55d4f17a35f2 -r 40e9de445038 src/libpst.h --- a/src/libpst.h Tue Mar 17 12:14:43 2009 -0700 +++ b/src/libpst.h Wed Mar 18 22:31:18 2009 -0700 @@ -172,6 +172,12 @@ } pst_string; +typedef struct pst_binary { + size_t size; + char *data; +} pst_binary; + + /** This struct defines an email message */ typedef struct pst_item_email { @@ -180,17 +186,15 @@ int autoforward; pst_string cc_address; pst_string bcc_address; - int32_t conversation_index; + pst_binary conversation_index; /** 1 = true, 0 = false */ int conversion_prohibited; /** 1 = true, 0 = false */ int delete_after_submit; /** 1 = true, 0 = false */ int delivery_report; - char *encrypted_body; - size_t encrypted_body_size; - char *encrypted_htmlbody; - size_t encrypted_htmlbody_size; + pst_binary encrypted_body; + pst_binary encrypted_htmlbody; pst_string header; pst_string htmlbody; /** 0=low, 1=normal, 2=high */ @@ -230,8 +234,7 @@ int32_t rtf_body_char_count; int32_t rtf_body_crc; pst_string rtf_body_tag; - char *rtf_compressed; - uint32_t rtf_compressed_size; + pst_binary rtf_compressed; /** 1 = true, 0 = false */ int rtf_in_sync; int32_t rtf_ws_prefix_count; @@ -256,8 +259,8 @@ typedef struct pst_item_folder { - int32_t email_count; - int32_t unseen_email_count; + int32_t item_count; + int32_t unseen_item_count; int32_t assoc_count; /** 1 = true, 0 = false */ int subfolder; @@ -401,8 +404,7 @@ pst_string filename1; pst_string filename2; pst_string mimetype; - char *data; - size_t size; + pst_binary data; uint64_t id2_val; /** calculated from id2_val during creation of record */ uint64_t i_id; @@ -506,8 +508,8 @@ int32_t message_codepage; int32_t message_size; pst_string outlook_version; - char *record_key; // probably 16 bytes long. - size_t record_key_size; + pst_binary record_key; + pst_binary predecessor_change; // was formerly stored in record_key /** 1 = true, 0 = false */ int response_requested; FILETIME *create_date; diff -r 55d4f17a35f2 -r 40e9de445038 src/lspst.c --- a/src/lspst.c Tue Mar 17 12:14:43 2009 -0700 +++ b/src/lspst.c Wed Mar 18 22:31:18 2009 -0700 @@ -11,7 +11,7 @@ struct file_ll { char *dname; int32_t stored_count; - int32_t email_count; + int32_t item_count; int32_t skip_count; int32_t type; }; @@ -29,10 +29,10 @@ void create_enter_dir(struct file_ll* f, pst_item *item) { pst_convert_utf8(item, &item->file_as); - f->email_count = 0; + f->item_count = 0; f->skip_count = 0; f->type = item->type; - f->stored_count = (item->folder) ? item->folder->email_count : 0; + f->stored_count = (item->folder) ? item->folder->item_count : 0; f->dname = (char*) xmalloc(strlen(item->file_as.str)+1); strcpy(f->dname, item->file_as.str); } diff -r 55d4f17a35f2 -r 40e9de445038 src/pst2dii.cpp.in --- a/src/pst2dii.cpp.in Tue Mar 17 12:14:43 2009 -0700 +++ b/src/pst2dii.cpp.in Wed Mar 18 22:31:18 2009 -0700 @@ -204,8 +204,8 @@ if (!(fp = fopen(temp, "wb"))) { WARN(("write_separate_attachment: Cannot open attachment save file \"%s\"\n", temp)); } else { - if (current_attach->data) - pst_fwrite(current_attach->data, 1, current_attach->size, fp); + if (current_attach->data.data) + pst_fwrite(current_attach->data.data, 1, current_attach->data.size, fp); else { (void)pst_attach_to_file(pst, current_attach, fp); } @@ -559,7 +559,7 @@ } else if (item->email->htmlbody.str) { removeCR(item->email->htmlbody.str); print_pdf(item->email->htmlbody.str); - } else if (item->email->encrypted_body || item->email->encrypted_htmlbody) { + } else if (item->email->encrypted_body.data || item->email->encrypted_htmlbody.data) { char ln[LINE_SIZE]; snprintf(ln, sizeof(ln), "%s", "The body of this email is encrypted. This isn't supported yet, but the body is now an attachment\n"); print_pdf(ln); @@ -569,8 +569,8 @@ int attach_num = 0; for (pst_item_attach* current_attach = item->attach; current_attach; current_attach = current_attach->next) { DEBUG_EMAIL(("Attempting Attachment encoding\n")); - if (!current_attach->data) { - DEBUG_EMAIL(("Data of attachment is NULL!. Size is supposed to be %i\n", current_attach->size)); + if (!current_attach->data.data) { + DEBUG_EMAIL(("Data of attachment is NULL!. Size is supposed to be %i\n", current_attach->data.size)); } string an = write_separate_attachment(f.name, current_attach, ++attach_num, pst); fprintf(dii_file, "@EATTACH %s\n", an.c_str()); @@ -588,7 +588,7 @@ f.email_count = 0; f.skip_count = 0; f.type = item->type; - f.stored_count = (item->folder) ? item->folder->email_count : 0; + f.stored_count = (item->folder) ? item->folder->item_count : 0; f.name = ((parent) ? parent->name + "/" : "") + string(item->file_as.str); } diff -r 55d4f17a35f2 -r 40e9de445038 src/readpst.c --- a/src/readpst.c Tue Mar 17 12:14:43 2009 -0700 +++ b/src/readpst.c Wed Mar 18 22:31:18 2009 -0700 @@ -21,7 +21,7 @@ char *dname; FILE * output; int32_t stored_count; - int32_t email_count; + int32_t item_count; int32_t skip_count; int32_t type; }; @@ -130,99 +130,120 @@ memset(&ff, 0, sizeof(ff)); create_enter_dir(&ff, outeritem); - while (d_ptr) { + for (; d_ptr; d_ptr = d_ptr->next) { DEBUG_MAIN(("main: New item record\n")); if (!d_ptr->desc) { + ff.skip_count++; DEBUG_WARN(("main: ERROR item's desc record is NULL\n")); - ff.skip_count++; + continue; } - else { - DEBUG_MAIN(("main: Desc Email ID %#"PRIx64" [d_ptr->d_id = %#"PRIx64"]\n", d_ptr->desc->i_id, d_ptr->d_id)); + DEBUG_MAIN(("main: Desc Email ID %#"PRIx64" [d_ptr->d_id = %#"PRIx64"]\n", d_ptr->desc->i_id, d_ptr->d_id)); + + item = pst_parse_item(&pstfile, d_ptr, NULL); + DEBUG_MAIN(("main: About to process item\n")); - item = pst_parse_item(&pstfile, d_ptr, NULL); - DEBUG_MAIN(("main: About to process item\n")); - if (item && item->subject.str) { - DEBUG_EMAIL(("item->subject = %s\n", item->subject.str)); - } - if (item) { - if (item->folder && d_ptr->child && item->file_as.str && (deleted_mode == DMODE_INCLUDE || strcasecmp(item->file_as.str, "Deleted Items"))) { - //if this is a non-empty folder other than deleted items, we want to recurse into it - if (output_mode != OUTPUT_QUIET) printf("Processing Folder \"%s\"\n", item->file_as.str); - process(item, d_ptr->child); + if (!item) { + ff.skip_count++; + DEBUG_MAIN(("main: A NULL item was seen\n")); + continue; + } + + if (item->subject.str) { + DEBUG_EMAIL(("item->subject = %s\n", item->subject.str)); + } - } else if (item->contact && (item->type == PST_TYPE_CONTACT)) { - if (mode == MODE_SEPARATE) mk_separate_file(&ff); - ff.email_count++; - DEBUG_MAIN(("main: Processing Contact\n")); - if (ff.type != PST_TYPE_CONTACT) { - DEBUG_MAIN(("main: I have a contact, but the folder type %"PRIi32" isn't a contacts folder. Processing anyway\n", ff.type)); - } - if (contact_mode == CMODE_VCARD) { - pst_convert_utf8_null(item, &item->comment); - write_vcard(ff.output, item, item->contact, item->comment.str); - } - else { - pst_convert_utf8(item, &item->contact->fullname); - pst_convert_utf8(item, &item->contact->address1); - fprintf(ff.output, "%s <%s>\n", item->contact->fullname.str, item->contact->address1.str); - } + if (item->folder && item->file_as.str) { + DEBUG_MAIN(("Processing Folder \"%s\"\n", item->file_as.str)); + if (output_mode != OUTPUT_QUIET) printf("Processing Folder \"%s\"\n", item->file_as.str); + ff.item_count++; + if (d_ptr->child && (deleted_mode == DMODE_INCLUDE || strcasecmp(item->file_as.str, "Deleted Items"))) { + //if this is a non-empty folder other than deleted items, we want to recurse into it + process(item, d_ptr->child); + } - } else if (item->email && (item->type == PST_TYPE_NOTE || item->type == PST_TYPE_REPORT)) { - char *extra_mime_headers = NULL; - if (mode == MODE_SEPARATE) mk_separate_file(&ff); - ff.email_count++; - DEBUG_MAIN(("main: Processing Email\n")); - if ((ff.type != PST_TYPE_NOTE) && (ff.type != PST_TYPE_REPORT)) { - DEBUG_MAIN(("main: I have an email type %"PRIi32", but the folder type %"PRIi32" isn't an email folder. Processing anyway\n", item->type, ff.type)); - } - write_normal_email(ff.output, ff.name, item, mode, mode_MH, &pstfile, save_rtf_body, &extra_mime_headers); + } else if (item->contact && (item->type == PST_TYPE_CONTACT)) { + if (!ff.type) ff.type = item->type; + DEBUG_MAIN(("main: Processing Contact\n")); + if (ff.type != PST_TYPE_CONTACT) { + ff.skip_count++; + DEBUG_MAIN(("main: I have a contact, but the folder type %"PRIi32" isn't a contacts folder. Skipping it\n", ff.type)); + } + else { + ff.item_count++; + if (mode == MODE_SEPARATE) mk_separate_file(&ff); + if (contact_mode == CMODE_VCARD) { + pst_convert_utf8_null(item, &item->comment); + write_vcard(ff.output, item, item->contact, item->comment.str); + } + else { + pst_convert_utf8(item, &item->contact->fullname); + pst_convert_utf8(item, &item->contact->address1); + fprintf(ff.output, "%s <%s>\n", item->contact->fullname.str, item->contact->address1.str); + } + } - } else if (item->journal && (item->type == PST_TYPE_JOURNAL)) { - if (mode == MODE_SEPARATE) mk_separate_file(&ff); - ff.email_count++; - DEBUG_MAIN(("main: Processing Journal Entry\n")); - if (ff.type != PST_TYPE_JOURNAL) { - DEBUG_MAIN(("main: I have a journal entry, but the folder type %"PRIi32" isn't a journal folder. Processing anyway\n", ff.type)); - } - fprintf(ff.output, "BEGIN:VJOURNAL\n"); - if (item->subject.str) { - pst_convert_utf8(item, &item->subject); - fprintf(ff.output, "SUMMARY:%s\n", pst_rfc2426_escape(item->subject.str)); - } - if (item->body.str) { - pst_convert_utf8(item, &item->body); - fprintf(ff.output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->body.str)); - } - if (item->journal->start) - fprintf(ff.output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(item->journal->start)); - fprintf(ff.output, "END:VJOURNAL\n\n"); + } else if (item->email && (item->type == PST_TYPE_NOTE || item->type == PST_TYPE_REPORT)) { + if (!ff.type) ff.type = item->type; + DEBUG_MAIN(("main: Processing Email\n")); + if ((ff.type != PST_TYPE_NOTE) && (ff.type != PST_TYPE_REPORT)) { + ff.skip_count++; + DEBUG_MAIN(("main: I have an email type %"PRIi32", but the folder type %"PRIi32" isn't an email folder. Skipping it\n", item->type, ff.type)); + } + else { + char *extra_mime_headers = NULL; + ff.item_count++; + if (mode == MODE_SEPARATE) mk_separate_file(&ff); + write_normal_email(ff.output, ff.name, item, mode, mode_MH, &pstfile, save_rtf_body, &extra_mime_headers); + } - } else if (item->appointment && (item->type == PST_TYPE_APPOINTMENT)) { - if (mode == MODE_SEPARATE) mk_separate_file(&ff); - ff.email_count++; - DEBUG_MAIN(("main: Processing Appointment Entry\n")); - if (ff.type != PST_TYPE_APPOINTMENT) { - DEBUG_MAIN(("main: I have an appointment, but folder type %"PRIi32" isn't an appointment folder. Processing anyway\n", ff.type)); - } - write_appointment(ff.output, item, item->appointment, item->create_date, item->modify_date); - - } else if (item->message_store) { - // there should only be one message_store, and we have already done it - DEBUG_MAIN(("item with message store content, type %i %s folder type %i, skipping it\n", item->type, item->ascii_type, ff.type)); + } else if (item->journal && (item->type == PST_TYPE_JOURNAL)) { + if (!ff.type) ff.type = item->type; + DEBUG_MAIN(("main: Processing Journal Entry\n")); + if (ff.type != PST_TYPE_JOURNAL) { + ff.skip_count++; + DEBUG_MAIN(("main: I have a journal entry, but the folder type %"PRIi32" isn't a journal folder. Skipping it\n", ff.type)); + } + else { + ff.item_count++; + if (mode == MODE_SEPARATE) mk_separate_file(&ff); + fprintf(ff.output, "BEGIN:VJOURNAL\n"); + if (item->subject.str) { + pst_convert_utf8(item, &item->subject); + fprintf(ff.output, "SUMMARY:%s\n", pst_rfc2426_escape(item->subject.str)); + } + if (item->body.str) { + pst_convert_utf8(item, &item->body); + fprintf(ff.output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->body.str)); + } + if (item->journal->start) + fprintf(ff.output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(item->journal->start)); + fprintf(ff.output, "END:VJOURNAL\n\n"); + } - } else { - // these all seem to be things that MS agrees are not included in the item count - //ff.skip_count++; - DEBUG_MAIN(("main: Unknown item type %i (%s) name (%s)\n", - item->type, item->ascii_type, item->file_as.str)); - } - pst_freeItem(item); - } else { + } else if (item->appointment && (item->type == PST_TYPE_APPOINTMENT)) { + if (!ff.type) ff.type = item->type; + DEBUG_MAIN(("main: Processing Appointment Entry\n")); + if (ff.type != PST_TYPE_APPOINTMENT) { ff.skip_count++; - DEBUG_MAIN(("main: A NULL item was seen\n")); + DEBUG_MAIN(("main: I have an appointment, but the folder type %"PRIi32" isn't an appointment folder. Skipping it\n", ff.type)); + } + else { + ff.item_count++; + if (mode == MODE_SEPARATE) mk_separate_file(&ff); + write_appointment(ff.output, item, item->appointment, item->create_date, item->modify_date); } - d_ptr = d_ptr->next; + + } else if (item->message_store) { + // there should only be one message_store, and we have already done it + ff.skip_count++; + DEBUG_MAIN(("item with message store content, type %i %s folder type %i, skipping it\n", item->type, item->ascii_type, ff.type)); + + } else { + ff.skip_count++; + DEBUG_MAIN(("main: Unknown item type %i (%s) name (%s)\n", + item->type, item->ascii_type, item->file_as.str)); } + pst_freeItem(item); } close_enter_dir(&ff); DEBUG_RET(); @@ -665,10 +686,10 @@ const int name_offset = 1; DEBUG_ENT("mk_separate_file"); DEBUG_MAIN(("opening next file to save email\n")); - if (f->email_count > 999999999) { // bigger than nine 9's + if (f->item_count > 999999999) { // bigger than nine 9's DIE(("mk_separate_file: The number of emails in this folder has become too high to handle")); } - sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->email_count + name_offset); + sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->item_count + name_offset); if (f->output) fclose(f->output); f->output = NULL; check_filename(f->name); @@ -732,7 +753,7 @@ : attach->filename1.str; DEBUG_ENT("write_separate_attachment"); - if (!attach->data) { + if (!attach->data.data) { // make sure we can fetch data from the id pst_index_ll *ptr = pst_getID(pst, attach->i_id); if (!ptr) { @@ -765,8 +786,8 @@ if (!(fp = fopen(temp, "w"))) { WARN(("write_separate_attachment: Cannot open attachment save file \"%s\"\n", temp)); } else { - if (attach->data) - pst_fwrite(attach->data, (size_t)1, attach->size, fp); + if (attach->data.data) + pst_fwrite(attach->data.data, (size_t)1, attach->data.size, fp); else { (void)pst_attach_to_file(pst, attach, fp); } @@ -810,9 +831,9 @@ char *attach_filename; char *enc = NULL; // base64 encoded attachment DEBUG_ENT("write_inline_attachment"); - DEBUG_EMAIL(("Attachment Size is %"PRIu64", id %#"PRIx64"\n", (uint64_t)attach->size, attach->i_id)); - if (attach->data) { - enc = base64_encode (attach->data, attach->size); + DEBUG_EMAIL(("Attachment Size is %"PRIu64", id %#"PRIx64"\n", (uint64_t)attach->data.size, attach->i_id)); + if (attach->data.data) { + enc = base64_encode (attach->data.data, attach->data.size); if (!enc) { DEBUG_EMAIL(("ERROR base64_encode returned NULL. Must have failed\n")); DEBUG_RET(); @@ -846,7 +867,7 @@ fprintf(f_output, "Content-Disposition: attachment; filename=\"%s\"\n\n", attach_filename); } - if (attach->data) { + if (attach->data.data) { pst_fwrite(enc, 1, strlen(enc), f_output); DEBUG_EMAIL(("Attachment Size after encoding is %i\n", strlen(enc))); free(enc); // caught by valgrind @@ -1256,9 +1277,9 @@ // multipart/report for DSN/MDN reports fprintf(f_output, "Content-Type: multipart/report; report-type=%s;\n\tboundary=\"%s\"\n", body_report, boundary); } - else if (item->attach || (item->email->rtf_compressed && save_rtf) - || item->email->encrypted_body - || item->email->encrypted_htmlbody) { + else if (item->attach || (item->email->rtf_compressed.data && save_rtf) + || item->email->encrypted_body.data + || item->email->encrypted_htmlbody.data) { // use multipart/mixed if we have attachments fprintf(f_output, "Content-Type: multipart/mixed;\n\tboundary=\"%s\"\n", boundary); } else { @@ -1282,43 +1303,43 @@ write_body_part(f_output, &item->email->htmlbody, "text/html", body_charset, boundary, pst); } - if (item->email->rtf_compressed && save_rtf) { + if (item->email->rtf_compressed.data && save_rtf) { pst_item_attach* attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach)); DEBUG_EMAIL(("Adding RTF body as attachment\n")); memset(attach, 0, sizeof(pst_item_attach)); attach->next = item->attach; item->attach = attach; - attach->data = lzfu_decompress(item->email->rtf_compressed, item->email->rtf_compressed_size, &attach->size); + attach->data.data = lzfu_decompress(item->email->rtf_compressed.data, item->email->rtf_compressed.size, &attach->data.size); attach->filename2.str = strdup(RTF_ATTACH_NAME); attach->filename2.is_utf8 = 1; attach->mimetype.str = strdup(RTF_ATTACH_TYPE); attach->mimetype.is_utf8 = 1; } - if (item->email->encrypted_body || item->email->encrypted_htmlbody) { + if (item->email->encrypted_body.data || item->email->encrypted_htmlbody.data) { // if either the body or htmlbody is encrypted, add them as attachments - if (item->email->encrypted_body) { + if (item->email->encrypted_body.data) { pst_item_attach* attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach)); DEBUG_EMAIL(("Adding Encrypted Body as attachment\n")); attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); memset(attach, 0, sizeof(pst_item_attach)); attach->next = item->attach; item->attach = attach; - attach->data = item->email->encrypted_body; - attach->size = item->email->encrypted_body_size; - item->email->encrypted_body = NULL; + attach->data.data = item->email->encrypted_body.data; + attach->data.size = item->email->encrypted_body.size; + item->email->encrypted_body.data = NULL; } - if (item->email->encrypted_htmlbody) { + if (item->email->encrypted_htmlbody.data) { pst_item_attach* attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach)); DEBUG_EMAIL(("Adding encrypted HTML body as attachment\n")); attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); memset(attach, 0, sizeof(pst_item_attach)); attach->next = item->attach; item->attach = attach; - attach->data = item->email->encrypted_htmlbody; - attach->size = item->email->encrypted_htmlbody_size; - item->email->encrypted_htmlbody = NULL; + attach->data.data = item->email->encrypted_htmlbody.data; + attach->data.size = item->email->encrypted_htmlbody.size; + item->email->encrypted_htmlbody.data = NULL; } write_email_body(f_output, "The body of this email is encrypted. This isn't supported yet, but the body is now an attachment\n"); } @@ -1332,12 +1353,12 @@ pst_convert_utf8_null(item, &attach->filename2); pst_convert_utf8_null(item, &attach->mimetype); DEBUG_EMAIL(("Attempting Attachment encoding\n")); - if (!attach->data && attach->mimetype.str && !strcmp(attach->mimetype.str, RFC822)) { + if (!attach->data.data && attach->mimetype.str && !strcmp(attach->mimetype.str, RFC822)) { DEBUG_EMAIL(("seem to have special embedded message attachment\n")); find_rfc822_headers(extra_mime_headers); write_embedded_message(f_output, attach, boundary, pst, extra_mime_headers); } - else if (attach->data || attach->i_id) { + else if (attach->data.data || attach->i_id) { if (mode == MODE_SEPARATE && !mode_MH) write_separate_attachment(f_name, attach, ++attach_num, pst); else @@ -1585,10 +1606,10 @@ void create_enter_dir(struct file_ll* f, pst_item *item) { pst_convert_utf8(item, &item->file_as); - f->email_count = 0; + f->item_count = 0; f->skip_count = 0; f->type = item->type; - f->stored_count = (item->folder) ? item->folder->email_count : 0; + f->stored_count = (item->folder) ? item->folder->item_count : 0; DEBUG_ENT("create_enter_dir"); if (mode == MODE_KMAIL) @@ -1600,7 +1621,6 @@ mk_separate_dir(item->file_as.str); f->name = (char*) xmalloc(10); memset(f->name, 0, 10); - // sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->email_count); } else { f->name = (char*) xmalloc(strlen(item->file_as.str)+strlen(OUTPUT_TEMPLATE)+1); sprintf(f->name, OUTPUT_TEMPLATE, item->file_as.str); @@ -1647,10 +1667,10 @@ void close_enter_dir(struct file_ll *f) { - DEBUG_MAIN(("main: Email Count for folder %s is %i\n", f->dname, f->email_count)); + DEBUG_MAIN(("main: processed item count for folder %s is %i, skipped %i, total %i \n", + f->dname, f->item_count, f->skip_count, f->stored_count)); if (output_mode != OUTPUT_QUIET) - printf("\t\"%s\" - %i items done, skipped %i, should have been %i\n", - f->dname, f->email_count, f->skip_count, f->stored_count); + printf("\t\"%s\" - %i items done.\n", f->dname, f->item_count); if (f->output) fclose(f->output); free(f->name); free(f->dname);