changeset 313:0f19cd173eab

fix to/cc/bcc recipients in .msg file output format
author Carl Byington <carl@five-ten-sg.com>
date Mon, 24 May 2010 21:50:19 -0700
parents b7f79da5fd55
children 6bf6b60a9751
files ChangeLog NEWS configure.in libpst.spec.in regression/regression-tests.bash src/msg.cpp src/readpst.c
diffstat 7 files changed, 84 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu May 06 13:32:17 2010 -0700
+++ b/ChangeLog	Mon May 24 21:50:19 2010 -0700
@@ -1,3 +1,7 @@
+LibPST 0.6.48 (2010-05-24)
+===============================
+    * fix to/cc/bcc recipients in .msg file output format
+
 LibPST 0.6.46 (2009-12-11)
 ===============================
     * add readpst -m switch to produce Outlook .msg files
--- a/NEWS	Thu May 06 13:32:17 2010 -0700
+++ b/NEWS	Mon May 24 21:50:19 2010 -0700
@@ -1,3 +1,4 @@
+0.6.48  2010-05-24 fix to/cc/bcc recipients in .msg file output format
 0.6.46  2009-12-11 add readpst -m switch to produce Outlook .msg files
 0.6.45  2009-11-18 patch from Hugo DesRosiers to export categories and notes into vcards
 0.6.44  2009-09-20 patch from Lee Ayres to add file name extensions in separate mode
--- a/configure.in	Thu May 06 13:32:17 2010 -0700
+++ b/configure.in	Mon May 24 21:50:19 2010 -0700
@@ -1,5 +1,5 @@
 AC_PREREQ(2.59)
-AC_INIT(libpst,0.6.47,carl@five-ten-sg.com)
+AC_INIT(libpst,0.6.48,carl@five-ten-sg.com)
 AC_CONFIG_SRCDIR([src/libpst.c])
 AC_CONFIG_HEADER([config.h])
 AM_INIT_AUTOMAKE
--- a/libpst.spec.in	Thu May 06 13:32:17 2010 -0700
+++ b/libpst.spec.in	Mon May 24 21:50:19 2010 -0700
@@ -146,6 +146,9 @@
 
 
 %changelog
+* Mon May 24 2010 Carl Byington <carl@five-ten-sg.com> - 0.6.48-1
+- fix to/cc/bcc recipients in .msg file output format
+
 * Fri Dec 11 2009 Carl Byington <carl@five-ten-sg.com> - 0.6.46-1
 - add readpst -m switch to produce Outlook .msg files
 
--- a/regression/regression-tests.bash	Thu May 06 13:32:17 2010 -0700
+++ b/regression/regression-tests.bash	Mon May 24 21:50:19 2010 -0700
@@ -54,6 +54,7 @@
     size=$(stat -c %s $fn)
     jobs=""
     [ -n "$val" ] && jobs="-j 0"
+    jobs="-j 0"
     rm -rf output$n
     if [ -z "$val" ] || [ $size -lt 10000000 ]; then
         echo $fn
@@ -68,7 +69,7 @@
             #$val ../src/readpst $jobs     -r    -cv -o output$n -d $ba.log $fn >$ba.err 2>&1
 
              # separate mode with filename extensions
-             $val ../src/readpst $jobs     -r -e -D -cv -o output$n -d $ba.log $fn >$ba.err 2>&1
+             $val ../src/readpst $jobs     -r -m -D -cv -o output$n -d $ba.log $fn >$ba.err 2>&1
 
             ## separate mode where we decode all attachments to binary files
             #$val ../src/readpst $jobs     -r -S -D -cv -o output$n -d $ba.log $fn >$ba.err 2>&1
@@ -101,29 +102,9 @@
 [ "$2" == "reg" ] && regression="yes"
 [ "$regression" == "yes" ] && val=""
 
-$func   1 ams.pst
-$func   2 sample_64.pst
-$func   3 test.pst
-$func   4 big_mail.pst
-$func   5 mbmg.archive.pst
-$func   6 Single2003-read.pst
-$func   7 Single2003-unread.pst
-$func   8 ol2k3high.pst
-$func   9 ol97high.pst
-$func  10 returned_message.pst
-$func  11 flow.pst
-$func  12 test-html.pst
-$func  13 test-text.pst
-$func  14 joe.romanowski.pst
-$func  15 hourig1.pst
-$func  16 test-mac.pst
-$func  17 harris.pst
-$func  18 spam.pst
-$func  19 rendgen.pst       # single email appointment
-$func  20 rendgen2.pst      # email appointment with no termination date
-$func  21 rendgen3.pst      # mime signed email
-$func  22 rendgen4.pst      # appointment test cases
-$func  23 rendgen5.pst      # appointment test cases
+#$func   1 mark.pst
+$func   2 mark-small.pst
+#$func   9 ol97high.pst
 
 [ -n "$val" ] && grep 'lost:' *err | grep -v 'lost: 0 '
 
--- a/src/msg.cpp	Thu May 06 13:32:17 2010 -0700
+++ b/src/msg.cpp	Mon May 24 21:50:19 2010 -0700
@@ -72,18 +72,25 @@
 static void string_property(GsfOutfile *out, property_list &prop, uint32_t tag, const char *contents, size_t size);
 static void string_property(GsfOutfile *out, property_list &prop, uint32_t tag, const char *contents, size_t size) {
     if (!contents) return;
+    size_t term = ((tag & 0x0000ffff) == 0x001e) ? 1 :
+                  ((tag & 0x0000ffff) == 0x001f) ? 2 : 0;  // null terminator
     vector<char> n(50);
     snprintf(&n[0], n.size(), "__substg1.0_%08X", tag);
+    fprintf(stdout, "dumping string property %08X size %d with data %s\n", tag, (int)size, contents);
     GsfOutput* dst = gsf_outfile_new_child(out, &n[0], false);
     gsf_output_write(dst, size, (const guint8*)contents);
+    if (term) {
+        memset(&n[0], 0, term);
+        gsf_output_write(dst, term, (const guint8*)&n[0]);
+        size += term;
+    }
     gsf_output_close(dst);
     g_object_unref(G_OBJECT(dst));
 
-    int bias = ((tag & 0x0000ffff) == 0x001e) ? 1 : 0;
     property p;
     p.tag      = tag;
     p.flags    = 0x6;   // make all the properties writable
-    p.length   = bias + size;
+    p.length   = size;
     p.reserved = 0;
     prop.push_back(p);
 }
@@ -282,27 +289,66 @@
 
     {
         vector<char> n(50);
-        snprintf(&n[0], n.size(), "__recip_version1.0_#%08X", top_head.recipient_count);
-        GsfOutput  *output = gsf_outfile_new_child(out, &n[0], true);
         {
-            int v = (email.message_recip_me) ? 1 :  // to
-                    (email.message_cc_me)    ? 2 :  // cc
-                                               3;   // bcc
-            property_list prop_list;
-            int_property(prop_list, 0x0C150003, 0x6, v);                        // PidTagRecipientType
-            int_property(prop_list, 0x30000003, 0x6, top_head.recipient_count); // PR_ROWID
-            GsfOutfile *out = GSF_OUTFILE (output);
-            string_property(out, prop_list, 0x3001001E, body_charset, item->file_as);
-            if (item->contact) {
-                string_property(out, prop_list, 0x3002001E, body_charset, item->contact->address1_transport);
-                string_property(out, prop_list, 0x3003001E, body_charset, item->contact->address1);
+            snprintf(&n[0], n.size(), "__recip_version1.0_#%08X", top_head.recipient_count);
+            GsfOutput  *output = gsf_outfile_new_child(out, &n[0], true);
+            {
+                int v = 1;  // to
+                property_list prop_list;
+                int_property(prop_list, 0x0C150003, 0x6, v);                        // PidTagRecipientType
+                int_property(prop_list, 0x30000003, 0x6, top_head.recipient_count); // PR_ROWID
+                GsfOutfile *out = GSF_OUTFILE (output);
+                string_property(out, prop_list, 0x3001001E, body_charset, item->file_as);
+                if (item->contact) {
+                    string_property(out, prop_list, 0x3002001E, body_charset, item->contact->address1_transport);
+                    string_property(out, prop_list, 0x3003001E, body_charset, item->contact->address1);
+                    string_property(out, prop_list, 0x5ff6001E, body_charset, item->contact->address1);
+                }
+                strin0_property(out, prop_list, 0x300B0102, body_charset, email.outlook_search_key);
+                write_properties(out, prop_list, (const guint8*)&top_head, 8);  // convenient 8 bytes of reserved zeros
+                gsf_output_close(output);
+                g_object_unref(G_OBJECT(output));
+                top_head.next_recipient++;
+                top_head.recipient_count++;
             }
-            strin0_property(out, prop_list, 0x300B0102, body_charset, email.outlook_search_key);
-            write_properties(out, prop_list, (const guint8*)&top_head, 8);  // convenient 8 bytes of reserved zeros
-            gsf_output_close(output);
-            g_object_unref(G_OBJECT(output));
-            top_head.next_recipient++;
-            top_head.recipient_count++;
+        }
+        if (email.cc_address.str) {
+            snprintf(&n[0], n.size(), "__recip_version1.0_#%08X", top_head.recipient_count);
+            GsfOutput  *output = gsf_outfile_new_child(out, &n[0], true);
+            {
+                int v = 2;  // cc
+                property_list prop_list;
+                int_property(prop_list, 0x0C150003, 0x6, v);                        // PidTagRecipientType
+                int_property(prop_list, 0x30000003, 0x6, top_head.recipient_count); // PR_ROWID
+                GsfOutfile *out = GSF_OUTFILE (output);
+                string_property(out, prop_list, 0x3001001E, body_charset, email.cc_address);
+                string_property(out, prop_list, 0x3003001E, body_charset, email.cc_address);
+                string_property(out, prop_list, 0x5ff6001E, body_charset, email.cc_address);
+                write_properties(out, prop_list, (const guint8*)&top_head, 8);  // convenient 8 bytes of reserved zeros
+                gsf_output_close(output);
+                g_object_unref(G_OBJECT(output));
+                top_head.next_recipient++;
+                top_head.recipient_count++;
+            }
+        }
+        if (email.bcc_address.str) {
+            snprintf(&n[0], n.size(), "__recip_version1.0_#%08X", top_head.recipient_count);
+            GsfOutput  *output = gsf_outfile_new_child(out, &n[0], true);
+            {
+                int v = 3;  // bcc
+                property_list prop_list;
+                int_property(prop_list, 0x0C150003, 0x6, v);                        // PidTagRecipientType
+                int_property(prop_list, 0x30000003, 0x6, top_head.recipient_count); // PR_ROWID
+                GsfOutfile *out = GSF_OUTFILE (output);
+                string_property(out, prop_list, 0x3001001E, body_charset, email.bcc_address);
+                string_property(out, prop_list, 0x3003001E, body_charset, email.bcc_address);
+                string_property(out, prop_list, 0x5ff6001E, body_charset, email.bcc_address);
+                write_properties(out, prop_list, (const guint8*)&top_head, 8);  // convenient 8 bytes of reserved zeros
+                gsf_output_close(output);
+                g_object_unref(G_OBJECT(output));
+                top_head.next_recipient++;
+                top_head.recipient_count++;
+            }
         }
     }
 
@@ -346,6 +392,8 @@
         a = a->next;
     }
 
+    write_properties(out, prop_list, (const guint8*)&top_head, sizeof(top_head));
+
     {
         GsfOutput  *output = gsf_outfile_new_child(out, "__nameid_version1.0", true);
         {
@@ -358,7 +406,6 @@
         }
     }
 
-    write_properties(out, prop_list, (const guint8*)&top_head, sizeof(top_head));
     gsf_output_close(output);
     g_object_unref(G_OBJECT(output));
 
--- a/src/readpst.c	Thu May 06 13:32:17 2010 -0700
+++ b/src/readpst.c	Mon May 24 21:50:19 2010 -0700
@@ -1510,7 +1510,7 @@
 
     if (item->email->bcc_address.str) {
         pst_convert_utf8(item, &item->email->bcc_address);
-        fprintf(f_output, "X-libpst-forensic-bcc: %s\n", item->email->bcc_address.str);
+        fprintf(f_output, "Bcc: %s\n", item->email->bcc_address.str);
     }
 
     // add our own mime headers