changeset 31:b88ceb81dba2

mege changes from Joe Nahmias
author carl
date Tue, 10 Jul 2007 17:17:28 -0700
parents 45eccad4b606
children c03974357771
files AUTHORS ChangeLog NEWS configure.in libpst.spec.in package src/debug.c src/define.h src/libpst.c src/libpst.h src/libstrfunc.c src/lspst.c src/readpst.c xml/libpst.in
diffstat 14 files changed, 611 insertions(+), 434 deletions(-) [+]
line wrap: on
line diff
--- a/AUTHORS	Sat Feb 25 16:16:15 2006 -0800
+++ b/AUTHORS	Tue Jul 10 17:17:28 2007 -0700
@@ -1,6 +1,8 @@
 Dave Smith <dave.s@earthcorp.com>
 
 With contributions by:
-    Joseph Nahmias <jello@costa.debian.org>
+    Joseph Nahmias <jello@costa.debian.org> <joe@nahmias.net>
     Carl Byington <carl@five-ten-sg.com>
     Arne Ahrend <aahrend@web.de>
+    Nigel Horne <njh@bandsman.co.uk>
+    Chris Hall
--- a/ChangeLog	Sat Feb 25 16:16:15 2006 -0800
+++ b/ChangeLog	Tue Jul 10 17:17:28 2007 -0700
@@ -1,3 +1,20 @@
+LibPST 0.5.5 (2007-07-10)
+===============================
+
+       * merge the following changes from Joe Nahmias version:
+       * Lots of memory fixes.  Thanks to Nigel Horne for his assistance
+       tracking these down!
+       * Fixed creation of vCards from contacts, thanks to Nigel Horne for
+       his help with this!
+       * fix for MIME multipart/alternative attachments.
+       * added -c options to readpst manpage.
+       * use 8.3 attachment filename if long filename isn't available.
+       * new -b option to skip rtf-body.rtf attachments.
+       * fix format of From header lines in mbox files.
+       * Add more appointment fields, thanks to Chris Hall for tracking
+       them down!
+
+
 LibPST 0.5.4 (2006-02-25)
 ===============================
 
--- a/NEWS	Sat Feb 25 16:16:15 2006 -0800
+++ b/NEWS	Tue Jul 10 17:17:28 2007 -0700
@@ -1,5 +1,6 @@
     $Id$
 
+0.5.5 2007-07-10 merge changes from Joe Nahmias version
 0.5.4 2006-02-25 add MH mode, generated filenames with no leading zeros
 0.5.3 2006-02-20 switch to gnu autoconf/automake
 0.5.2 2006-02-18 add pst2ldif, fix btree processing in libpst.c
--- a/configure.in	Sat Feb 25 16:16:15 2006 -0800
+++ b/configure.in	Tue Jul 10 17:17:28 2007 -0700
@@ -1,13 +1,33 @@
 AC_INIT(configure.in)
 
 AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(libpst,0.5.4)
+AM_INIT_AUTOMAKE(libpst,0.5.5)
 AC_PATH_PROGS(BASH, bash)
 
 AC_LANG_CPLUSPLUS
 AC_PROG_CXX
 AC_PROG_LIBTOOL
 
+# The following lines adds the --enable-pst-debug option to configure:
+#
+# Give the user the choice to enter one of these:
+# --enable-pst-debug
+# --enable-pst-debug=yes
+# --enable-pst-debug=no
+#
+AC_MSG_CHECKING([whether we are enabling pst debug code])
+AC_ARG_ENABLE(pst-debug,
+      AC_HELP_STRING([--enable-pst-debug], [enable pst debug code]),
+      [if test "${enable_pst_debug}" = "no" ; then
+          AC_MSG_RESULT([no])
+      else
+          AC_DEFINE(DEBUG_ALL, 1, Define to 1 to enable pst debug code)
+          AC_MSG_RESULT([yes])
+      fi],
+      # Default value for configure
+      AC_MSG_RESULT([no])
+      )
+
 AC_OUTPUT(                  \
     Makefile                \
     libpst.spec             \
--- a/libpst.spec.in	Sat Feb 25 16:16:15 2006 -0800
+++ b/libpst.spec.in	Tue Jul 10 17:17:28 2007 -0700
@@ -4,7 +4,7 @@
 Name:               @PACKAGE@
 Version:            @VERSION@
 Release:            %{?custom_release}%{!?custom_release:1}
-Copyright:          GPL
+License:            GPL
 Group:              System Environment/Daemons
 Source:             http://www.five-ten-sg.com/@PACKAGE@/packages/@PACKAGE@-@VERSION@.tar.gz
 BuildRoot:          %{_tmppath}/%{name}-%{version}-buildroot
@@ -67,6 +67,9 @@
 
 
 %changelog
-* Sun Feb 19 2006 Carl Byington 1.0
+* Tue Jul 10 2007 Carl Byington 0.5.5
+- merge changes from Joe Nahmias version
+
+* Sun Feb 19 2006 Carl Byington 0.5.3
 - initial spec file using autoconf and http://www.fedora.us/docs/rpm-packaging-guidelines.html
 
--- a/package	Sat Feb 25 16:16:15 2006 -0800
+++ b/package	Tue Jul 10 17:17:28 2007 -0700
@@ -12,18 +12,6 @@
 ./configure >/dev/null
 (cd xml; make; make distclean)
 cp -a html/*html $web
-if [ "$1" == "test" ]; then
-    make
-    pst=/home/ldap/outlook.pst
-    rm -f pst2ldif.log my.log
-    src/pst2ldif -b 'o=ams-cc.com, c=US' -c 'newPerson' $pst >ams.ldif
-    src/readpstlog pst2ldif.log | less >my.log
-    hexdump -C -v $pst >pst.dump
-    chown --recursive carl:carl *
-    exit
-else
-    rm -f pst2ldif.log my.log ams.ldif pst.dump
-fi
 make distcheck >$distlog 2>&1
 
 if [ $? -eq 0 ]; then
@@ -41,20 +29,28 @@
         cd ..
 
         # build rpm on target
-        target=host62
-        scp $BALL $target:/tmp
-        ssh $target "cd /tmp; rpmbuild -ta $BALL"
+        target5=pmg2
+        scp $BALL $target5:/tmp
+        ssh $target5 "cd /tmp; rpmbuild -ta $BALL"
+
+        # build rpm on target
+        target4=host62
+        scp $BALL $target4:/tmp
+        ssh $target4 "cd /tmp; rpmbuild -ta $BALL"
 
         # add packages to the web site
         wp=$web/packages
         wp4=$wp/centos4
-        mkdir -p $wp4
+        wp5=$wp/centos5
+        mkdir -p $wp4 $wp5
         rp=/usr/src/redhat
         mv -f $BALL $wp
-        scp $target:$rp/SRPMS/$NAME-$VER*rpm $wp
-        scp $target:$rp/RPMS/i386/$NAME-$VER*rpm $wp4
-        (cd $web; chown --recursive web:web .; ls -alR)
+        scp $target4:$rp/SRPMS/$NAME-$VER*rpm $wp
+        scp $target4:$rp/RPMS/i386/$NAME-$VER*rpm $wp4
+        scp $target5:$rp/RPMS/i386/$NAME-$VER*rpm $wp5
+        (cd $web; chown --recursive web:web *; ls -alR)
         rpm -ql -p $wp4/$NAME-$VER*6.rpm
+        rpm -ql -p $wp5/$NAME-$VER*6.rpm
     fi
 else
     tail -10 $distlog
--- a/src/debug.c	Sat Feb 25 16:16:15 2006 -0800
+++ b/src/debug.c	Tue Jul 10 17:17:28 2007 -0700
@@ -29,13 +29,13 @@
 void _debug_init(char *fname);
 void _debug_msg_info (int line, char *file, int type);
 void _debug_msg(char* fmt, ...);
-void _debug_hexdump(char *x, int y, int cols);
+void _debug_hexdump(unsigned char *x, int y, int cols);
 void _debug_func(char *function);
 void _debug_func_ret();
 void _debug_close();
 void _debug_write();
 void _debug_write_msg(struct _debug_item *item, char *fmt, va_list *ap, int size);
-void _debug_write_hex(struct _debug_item *item, char *buf, int size, int col);
+void _debug_write_hex(struct _debug_item *item, unsigned char *buf, int size, int col);
 void * xmalloc(size_t size);
 
 // the largest text size we will store in memory. Otherwise we
@@ -159,13 +159,16 @@
 #else
   f = vsnprintf(x, 1, fmt, ap);
 #endif
+  va_end(ap);  // must be called after vsnprintf()
 
   if (f > 0 && f < MAX_MESSAGE_SIZE) {
     info_ptr->text = (char*) xmalloc(f+1);
+    va_start(ap, fmt);
     if ((g = vsnprintf(info_ptr->text, f, fmt, ap)) == -1) {
       fprintf(stderr, "_debug_msg: Dieing! vsnprintf returned -1 for format \"%s\"\n", fmt);
       exit(-2);
     }
+    va_end(ap);
     info_ptr->text[g] = '\0';
     if (f != g) {
       fprintf(stderr, "_debug_msg: f != g\n");
@@ -175,7 +178,9 @@
     temp = info_ptr;
     _debug_write(); // dump the current messages
     info_ptr = temp;
+    va_start(ap, fmt);
     _debug_write_msg(info_ptr, fmt, &ap, f);
+    va_end(ap);
     free(info_ptr->function);
     free(info_ptr->file);
     free(info_ptr);
@@ -185,7 +190,6 @@
     fprintf(stderr, "_debug_msg: error getting requested size of debug message\n");
     info_ptr->text = "ERROR Saving\n";
   }
-  va_end(ap);
 
   if (item_head == NULL)
     item_head = info_ptr;
@@ -202,7 +206,7 @@
   }
 }
 
-void _debug_hexdump(char *x, int y, int cols) {
+void _debug_hexdump(unsigned char *x, int y, int cols) {
   struct _debug_item *temp;
   if (debug_fp == NULL)
     return;
@@ -261,7 +265,7 @@
 
 void _debug_write() {
   size_t size, ptr, funcname, filename, text, end;
-  char *buf, rec_type;
+  char *buf = NULL, rec_type;
   long index_pos = ftell (debug_fp), file_pos = index_pos;
   // add 2. One for the pointer to the next index, 
   // one for the count of this index
@@ -287,6 +291,7 @@
     index[index_ptr++] = file_pos;
     size = strlen(item_ptr->function)+strlen(item_ptr->file)+
       strlen(item_ptr->text) + 3; //for the three \0s
+    if (buf) free(buf);
     buf = xmalloc(size+1);
     ptr = 0;
     funcname=ptr;
@@ -318,6 +323,7 @@
       fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp);
     }
     fwrite(buf, 1, ptr, debug_fp);
+    if (buf) free(buf); buf = NULL;
     item_head = item_ptr->next;
     free(item_ptr->function);
     free(item_ptr->file);
@@ -334,6 +340,7 @@
   fseek(debug_fp, 0, SEEK_END);
   item_ptr = item_head = item_tail = NULL;
   free(index);
+  if (buf) free(buf); buf = NULL;
 }
 
 void _debug_write_msg(struct _debug_item *item, char *fmt, va_list *ap, int size) {
@@ -394,7 +401,7 @@
   // that should do it...
 }
 
-void _debug_write_hex(struct _debug_item *item, char *buf, int size, int col) {
+void _debug_write_hex(struct _debug_item *item, unsigned char *buf, int size, int col) {
   struct _debug_file_rec_l lfile_rec;
   unsigned char rec_type;
   int index_size = 3 * sizeof(int);
--- a/src/define.h	Sat Feb 25 16:16:15 2006 -0800
+++ b/src/define.h	Tue Jul 10 17:17:28 2007 -0700
@@ -5,9 +5,9 @@
  *			  dave.s@earthcorp.com
  */
 
-// last one wins
-#define DEBUG_ALL
-#undef DEBUG_ALL
+#ifdef HAVE_CONFIG_H
+	#include "config.h"
+#endif
 
 #ifndef DEFINEH_H
 #define DEFINEH_H
@@ -60,7 +60,7 @@
 void _debug_init(char *fname);
 void _debug_msg_info (int line, char *file, int type);
 void _debug_msg_text(char* fmt, ...);
-void _debug_hexdump(char *x, int y, int cols);
+void _debug_hexdump(unsigned char *x, int y, int cols);
 void _debug_func(char *function);
 void _debug_func_ret();
 void _debug_close(void);
--- a/src/libpst.c	Sat Feb 25 16:16:15 2006 -0800
+++ b/src/libpst.c	Tue Jul 10 17:17:28 2007 -0700
@@ -119,13 +119,8 @@
 
 int32_t pst_open(pst_file *pf, char *name, char *mode) {
 	u_int32_t sig;
-	//	unsigned char ind_type;
 
 	DEBUG_ENT("pst_open");
-#ifdef _MSC_VER
-	// set the default open mode for windows
-	_fmode = _O_BINARY;
-#endif //_MSC_VER
 
 	if (!pf) {
 		WARN (("cannot be passed a NULL pst_file\n"));
@@ -134,21 +129,24 @@
 	}
 	memset(pf, 0, sizeof(pst_file));
 
+#ifdef _MSC_VER
+	// set the default open mode for windows
+	_fmode = _O_BINARY;
+#endif //_MSC_VER
 	if ((pf->fp = fopen(name, mode)) == NULL) {
 		WARN(("cannot open PST file. Error\n"));
 		DEBUG_RET();
 		return -1;
 	}
+
+	// Check pst file magic
 	if (fread(&sig, sizeof(sig), 1, pf->fp) == 0) {
 		fclose(pf->fp);
 		WARN(("cannot read signature from PST file. Closing on error\n"));
 		DEBUG_RET();
 		return -1;
 	}
-
-	// architecture independant byte-swapping (little, big, pdp)
-	LE32_CPU(sig);
-
+	LE32_CPU(sig);	// architecture independant byte-swapping (little, big, pdp)
 	DEBUG_INFO(("sig = %X\n", sig));
 	if (sig != PST_SIGNATURE) {
 		fclose(pf->fp);
@@ -156,6 +154,8 @@
 		DEBUG_RET();
 		return -1;
 	}
+
+	// read index type
 	_pst_getAtPos(pf->fp, INDEX_TYPE_OFFSET, &(pf->ind_type), sizeof(unsigned char));
 	DEBUG_INFO(("index_type = %i\n", pf->ind_type));
 	if (pf->ind_type != 0x0E) {
@@ -164,6 +164,7 @@
 		return -1;
 	}
 
+	// read encryption setting
 	_pst_getAtPos(pf->fp, ENC_OFFSET, &(pf->encryption), sizeof(unsigned char));
 	DEBUG_INFO(("encrypt = %i\n", pf->encryption));
 
@@ -240,8 +241,9 @@
 			size = _pst_ff_getID2data(pf, ptr, &h);
 		} else {
 			DEBUG_WARN(("Couldn't find ID pointer. Cannot handle attachment\n"));
+			size = 0;
 		}
-		attach->size = size; // may aswell update it to what is correct for this instance
+		attach->size = size; // may as well update it to what is correct for this instance
 	} else {
 		size = attach->size;
 	}
@@ -261,6 +263,7 @@
 			size = _pst_ff_getID2data(pf, ptr, &h);
 		} else {
 			DEBUG_WARN(("Couldn't find ID pointer. Cannot save attachment to file\n"));
+			size = 0;
 		}
 		attach->size = size;
 	} else {
@@ -285,15 +288,16 @@
 			size = _pst_ff_getID2data(pf, ptr, &h);
 			// will need to encode any bytes left over
 			c = base64_encode(h.base64_extra_chars, h.base64_extra);
-			pst_fwrite(c, 1, strlen(c), fp);
+			if (c) pst_fwrite(c, 1, strlen(c), fp);
 		} else {
 			DEBUG_WARN (("Couldn't find ID pointer. Cannot save attachement to Base64\n"));
+			size = 0;
 		}
 		attach->size = size;
 	} else {
 		// encode the attachment to the file
 		c = base64_encode(attach->data, attach->size);
-		pst_fwrite(c, 1, strlen(c), fp);
+		if (c) pst_fwrite(c, 1, strlen(c), fp);
 		size = attach->size;
 	}
 	DEBUG_RET();
@@ -350,13 +354,11 @@
 	// for PST files this will load up ID2 0x61 and check it's "list" attribute.
 	pst_desc_ll *p;
 	pst_num_array *na;
-	//	pst_index_ll *list;
-	pst_index2_ll *list2;//, *t;
+	pst_index2_ll *list2;
 	unsigned char * buffer=NULL, *headerbuffer=NULL;//, *tc;
 	pst_x_attrib xattrib;
 	int32_t bptr = 0, bsize, hsize, tint, err=0, x;
 	pst_x_attrib_ll *ptr, *p_head=NULL, *p_sh=NULL, *p_sh2=NULL;
-	char *wt;
 
 	DEBUG_ENT("pst_loadExtendedAttributes");
 	if ((p = _pst_getDptr(pf, 0x61)) == NULL) {
@@ -390,6 +392,7 @@
 	}
 
 	if (!buffer) {
+		if (na) _pst_free_list(na);
 		DEBUG_WARN(("No extended attributes buffer found. Not processing\n"));
 		DEBUG_RET();
 		return 0;
@@ -414,6 +417,7 @@
 		if (xattrib.type & 0x0001) { // if the Bit 1 is set
 			// pointer to Unicode field in buffer
 			if (xattrib.extended < hsize) {
+				char *wt;
 				// copy the size of the header. It is 32 bit int
 				memcpy(&tint, &(headerbuffer[xattrib.extended]), sizeof(tint));
 				LE32_CPU(tint);
@@ -421,6 +425,7 @@
 				memset(wt, 0, tint+2);
 				memcpy(wt, &(headerbuffer[xattrib.extended+sizeof(tint)]), tint);
 				ptr->data = _pst_wide_to_single(wt, tint);
+				free(wt);
 				DEBUG_INDEX(("Read string (converted from UTF-16): %s\n", ptr->data));
 			} else {
 				DEBUG_INDEX(("Cannot read outside of buffer [%i !< %i]\n", xattrib.extended, hsize));
@@ -463,8 +468,8 @@
 		LE16_CPU(xattrib.map);
 		bptr += sizeof(xattrib);
 	}
-	if (buffer) 	  free(buffer);
-	if (headerbuffer) free(headerbuffer);
+	if (list2) _pst_free_id2(list2);
+	if (na)    _pst_free_list(na);
 	pf->x_head = p_head;
 	DEBUG_RET();
 	return 1;
@@ -981,12 +986,14 @@
 
 	if (!d_ptr->desc) {
 		DEBUG_WARN(("why is d_ptr->desc == NULL? I don't want to do anything else with this record\n"));
+		if (id2_head) _pst_free_id2(id2_head);
 		DEBUG_RET();
 		return NULL;
 	}
 
 	if ((list = _pst_parse_block(pf, d_ptr->desc->id, id2_head)) == NULL) {
 		DEBUG_WARN(("_pst_parse_block() returned an error for d_ptr->desc->id [%#x]\n", d_ptr->desc->id));
+		if (id2_head) _pst_free_id2(id2_head);
 		DEBUG_RET();
 		return NULL;
 	}
@@ -996,11 +1003,13 @@
 
 	if (_pst_process(list, item)) {
 		DEBUG_WARN(("_pst_process() returned non-zero value. That is an error\n"));
-		_pst_free_list(list);
+		if (item)	  free(item);
+		if (list)	  _pst_free_list(list);
+		if (id2_head) _pst_free_id2(id2_head);
 		DEBUG_RET();
 		return NULL;
 	} else {
-		_pst_free_list(list);
+		if (list) _pst_free_list(list);
 		list = NULL; //_pst_process will free the items in the list
 	}
 
@@ -1015,8 +1024,10 @@
 		DEBUG_EMAIL(("ATTACHEMENT processing attachement\n"));
 		if ((list = _pst_parse_block(pf, id_ptr->id, id2_head)) == NULL) {
 			DEBUG_WARN(("ERROR error processing main attachment record\n"));
-		  //  DEBUG_RET();
-		  //  return NULL;
+			if (item) free(item);
+			if (id2_head) _pst_free_id2(id2_head);
+			DEBUG_RET();
+			return NULL;
 		}
 		else {
 			x = 0;
@@ -1030,11 +1041,14 @@
 
 			if (_pst_process(list, item)) {
 				DEBUG_WARN(("ERROR _pst_process() failed with attachments\n"));
-				_pst_free_list(list);
+				if (item)	  free(item);
+				if (list)	  _pst_free_list(list);
+				if (id2_head) _pst_free_id2(id2_head);
 				DEBUG_RET();
 				return NULL;
 			}
-			_pst_free_list(list);
+			if (list) _pst_free_list(list);
+			list = NULL;
 
 			// now we will have initial information of each attachment stored in item->attach...
 			// we must now read the secondary record for each based on the id2 val associated with
@@ -1052,11 +1066,13 @@
 				  }
 				  if (_pst_process(list, item)) {
 					  DEBUG_WARN(("ERROR _pst_process() failed with an attachment\n"));
-					  _pst_free_list(list);
+					  if (list) _pst_free_list(list);
+					  list = NULL;
 					  attach = attach->next;
 					  continue;
 				  }
-				  _pst_free_list(list);
+				  if (list) _pst_free_list(list);
+				  list = NULL;
 				  if ((id_ptr = _pst_getID2(id2_head, attach->id2_val))) {
 					  // id2_val has been updated to the ID2 value of the datablock containing the
 					  // attachment data
@@ -1073,6 +1089,7 @@
 	}
 
 	_pst_free_id2(id2_head);
+	id2_head = NULL;
 	DEBUG_RET();
 	return item;
 }
@@ -1281,7 +1298,8 @@
 				fr_ptr += sizeof(table2_rec);
 			} else {
 				WARN(("Missing code for block_type %i\n", block_type));
-				if (buf) free(buf);
+				if (buf)	 free(buf);
+				if (na_head) _pst_free_list(na_head);
 				DEBUG_RET();
 				return NULL;
 			}
@@ -1377,7 +1395,7 @@
 					}
 
 					// plus one for good luck (and strings) we will null terminate all reads
-					na_ptr->items[x]->data = (char*) xmalloc(size+1);
+					na_ptr->items[x]->data = (unsigned char*) xmalloc(size+1);
 					memcpy(na_ptr->items[x]->data, &(buf[t_ptr]), size);
 					na_ptr->items[x]->data[size] = '\0'; // null terminate buffer
 
@@ -1407,6 +1425,8 @@
 					na_ptr->items[x]->type = table_rec.ref_type;
 			} else {
 				WARN(("ERROR Unknown ref_type %#x\n", table_rec.ref_type));
+				if (buf)	 free(buf);
+				if (na_head) _pst_free_list(na_head);
 				DEBUG_RET();
 				return NULL;
 			}
@@ -3002,6 +3022,17 @@
 							DEBUG_EMAIL(("Phone Call\n")); break;
 					}
 					break;
+				case 0x8215: // All day appointment flag
+					DEBUG_EMAIL(("All day flag - "));
+					MALLOC_APPOINTMENT(item);
+					if (*(int16_t*)list->items[x]->data != 0) {
+						DEBUG_EMAIL(("True\n"));
+						item->appointment->all_day = 1;
+					} else {
+						DEBUG_EMAIL(("False\n"));
+						item->appointment->all_day = 0;
+					}
+					break;
 				case 0x8234: // TimeZone as String
 					DEBUG_EMAIL(("TimeZone of times - "));
 					MALLOC_APPOINTMENT(item);
@@ -3243,6 +3274,7 @@
 	pst_index_ll *i_ptr = NULL;
 	pst_index2_ll *i2_ptr = NULL;
 	DEBUG_ENT("_pst_build_id2");
+
 	if (head_ptr) {
 		head = head_ptr;
 		while (head_ptr) head_ptr = (tail = head_ptr)->next;
@@ -3250,6 +3282,7 @@
 	if (_pst_read_block_size(pf, list->offset, list->size, &buf, PST_NO_ENC, 0) < list->size) {
 		//an error occured in block read
 		WARN(("block read error occured. offset = %#x, size = %#x\n", list->offset, list->size));
+		if (buf) free(buf);
 		DEBUG_RET();
 		return NULL;
 	}
@@ -3261,6 +3294,7 @@
 
 	if (block_head.type != 0x0002) { // some sort of constant?
 		WARN(("Unknown constant [%#x] at start of id2 values [offset %#x].\n", block_head.type, list->offset));
+		if (buf) free(buf);
 		DEBUG_RET();
 		return NULL;
 	}
@@ -3513,7 +3547,7 @@
 }
 
 
-int32_t _pst_getBlockOffset(char *buf, int32_t read_size, int32_t i_offset, int32_t offset, pst_block_offset *p) {
+int32_t _pst_getBlockOffset(unsigned char *buf, int32_t read_size, int32_t i_offset, int32_t offset, pst_block_offset *p) {
 	int32_t of1 = offset>>4;
 	DEBUG_ENT("_pst_getBlockOffset");
 	if (!p || !buf || (i_offset == 0) || (i_offset+2+of1+sizeof(*p) > read_size)) {
@@ -3679,8 +3713,10 @@
 	unsigned char fdepth;
 	pst_index_ll *ptr = NULL;
 	size_t rsize, z;
+
 	DEBUG_ENT("_pst_read_block_size");
 	DEBUG_READ(("Reading block from %#x, %i bytes\n", offset, size));
+
 	fpos = ftell(pf->fp);
 	fseek(pf->fp, offset, SEEK_SET);
 	if (*buf) {
@@ -3688,7 +3724,7 @@
 		free(*buf);
 	}
 
-	*buf = (void*) xmalloc(size+1); //plus one so that we can NULL terminate it later
+	*buf = (void*) xmalloc(size+1); //plus one so that we can NUL terminate it later
 	rsize = fread(*buf, 1, size, pf->fp);
 	if (rsize != size) {
 		DEBUG_WARN(("Didn't read all that I could. fread returned less [%i instead of %i]\n", rsize, size));
@@ -3894,7 +3930,7 @@
 			*(h->buf) = b;
 		} else if ((h->base64 == 1) && h->fp) {
 			t = base64_encode(b, ret);
-			pst_fwrite(t, 1, strlen(t), h->fp);
+			if (t) pst_fwrite(t, 1, strlen(t), h->fp);
 			free(b);
 		} else if (h->fp) {
 			pst_fwrite(b, 1, ret, h->fp);
@@ -3923,8 +3959,10 @@
 	unsigned char fdepth;
 
 	DEBUG_ENT("_pst_ff_compile_ID");
-	if ((a = _pst_ff_getIDblock(pf, id, &buf3))==0)
+	if ((a = _pst_ff_getIDblock(pf, id, &buf3))==0) {
+		if (buf3) free(buf3);
 		return 0;
+	}
 	if ((buf3[0] != 0x1)) { // if bit 8 is set) {
 		//	if ((buf3)[0] != 0x1 && (buf3)[1] > 4) {
 		DEBUG_WARN(("WARNING: buffer doesn't start with 0x1, but I expected it to or doesn't have it's two-bit set!\n"));
@@ -3934,7 +3972,7 @@
 			*(h->buf) = buf3;
 		else if (h->base64 == 1 && h->fp) {
 			t = base64_encode(buf3, a);
-			pst_fwrite(t, 1, strlen(t), h->fp);
+			if (t) pst_fwrite(t, 1, strlen(t), h->fp);
 			free(buf3);
 		} else if (h->fp) {
 			pst_fwrite(buf3, 1, a, h->fp);
@@ -3978,7 +4016,7 @@
 				memcpy(h->base64_extra_chars, &(buf2[z-b]), b);
 				h->base64_extra = b;
 				t = base64_encode(buf2, z-b);
-				pst_fwrite(t, 1, strlen(t), h->fp);
+				if (t) pst_fwrite(t, 1, strlen(t), h->fp);
 				DEBUG_READ(("writing %i bytes to file as base64 [%i]. Currently %i\n",
 						z, strlen(t), size));
 			}
--- a/src/libpst.h	Sat Feb 25 16:16:15 2006 -0800
+++ b/src/libpst.h	Tue Jul 10 17:17:28 2007 -0700
@@ -378,6 +378,7 @@
   char *timezonestring;
   int32_t showas;
   int32_t label;
+  int32_t all_day;
 } pst_item_appointment;
 
 typedef struct _pst_item {
@@ -420,10 +421,10 @@
   int32_t index1_count;
   int32_t index2;
   int32_t index2_count;
-  FILE * fp;
-  size_t size;
-  unsigned char encryption;
-  unsigned char ind_type;
+  FILE * fp;				// file pointer to opened PST file
+  size_t size;				// pst file size
+  unsigned char encryption; // pst encryption setting
+  unsigned char ind_type;	// pst index type
 } pst_file;
 
 typedef struct _pst_block_offset {
@@ -477,7 +478,7 @@
 int32_t _pst_free_id (pst_index_ll *head);
 int32_t _pst_free_desc (pst_desc_ll *head);
 int32_t _pst_free_xattrib(pst_x_attrib_ll *x);
-int32_t _pst_getBlockOffset(char *buf, int32_t read_size, int32_t i_offset, int32_t offset, pst_block_offset *p);
+int32_t _pst_getBlockOffset(unsigned char *buf, int32_t read_size, int32_t i_offset, int32_t offset, pst_block_offset *p);
 pst_index2_ll * _pst_build_id2(pst_file *pf, pst_index_ll* list, pst_index2_ll* head_ptr);
 pst_index_ll * _pst_getID(pst_file* pf, u_int32_t id);
 pst_index_ll * _pst_getID2(pst_index2_ll * ptr, u_int32_t id);
--- a/src/libstrfunc.c	Sat Feb 25 16:16:15 2006 -0800
+++ b/src/libstrfunc.c	Tue Jul 10 17:17:28 2007 -0700
@@ -27,7 +27,7 @@
   //register void *dte=data + size;
   register int nc=0;
   
-  if(data == NULL)
+  if ( data == NULL || size == 0 )
     return NULL;
   
   ou=output=(char *)malloc(size / 3 * 4 + (size / 50) + 5);
--- a/src/lspst.c	Sat Feb 25 16:16:15 2006 -0800
+++ b/src/lspst.c	Tue Jul 10 17:17:28 2007 -0700
@@ -37,8 +37,8 @@
 char *rfc2426_escape(char *str);
 char *rfc2445_datetime_format(FILETIME *ft);
 // }}}1
-#ifndef DEBUG_MAIN
-	#define DEBUG_MAIN(x) debug_print x;
+#ifndef LSPST_DEBUG_MAIN
+	#define LSPST_DEBUG_MAIN(x) debug_print x;
 #endif
 // int main(int argc, char** argv) {{{1
 int main(int argc, char** argv) {
@@ -49,7 +49,7 @@
 	pst_desc_ll *d_ptr;
 	char *temp = NULL; //temporary char pointer
 	int skip_child = 0;
-	struct file_ll	*f, *head;
+	struct file_ll	*f = NULL, *head = NULL;
 	// }}}2
 
 	if (argc <= 1)
@@ -92,12 +92,12 @@
 	head->dname = (char*) malloc(strlen(item->file_as)+1);
 	strcpy(head->dname, item->file_as);
 	head->type = item->type;
-	DEBUG_MAIN(("head @ %p: name = '%s', dname = '%s', next = %p.\n", head, head->name, head->dname, head->next));
+	LSPST_DEBUG_MAIN(("head @ %p: name = '%s', dname = '%s', next = %p.\n", head, head->name, head->dname, head->next));
 
 	if ((d_ptr = pst_getTopOfFolders(&pstfile, item)) == NULL) {
 		DIE(("Top of folders record not found. Cannot continue\n"));
 	}
-	DEBUG_MAIN(("d_ptr(TOF) = %p.\n", d_ptr));
+	LSPST_DEBUG_MAIN(("d_ptr(TOF) = %p.\n", d_ptr));
 
 	if (item){
 		_pst_freeItem(item);
@@ -105,21 +105,21 @@
 	}
 
 	d_ptr = d_ptr->child; // do the children of TOPF
-	DEBUG_MAIN(("d_ptr(TOF->child) = %p.\n", d_ptr));
+	LSPST_DEBUG_MAIN(("d_ptr(TOF->child) = %p.\n", d_ptr));
 
-	DEBUG_MAIN(("main: About to do email stuff\n"));
+	LSPST_DEBUG_MAIN(("main: About to do email stuff\n"));
 	while (d_ptr != NULL) {
 		// Process d_ptr {{{2
-		DEBUG_MAIN(("main: New item record, d_ptr = %p.\n", d_ptr));
+		LSPST_DEBUG_MAIN(("main: New item record, d_ptr = %p.\n", d_ptr));
 		if (d_ptr->desc == NULL) {
 			DEBUG_WARN(("main: ERROR ?? item's desc record is NULL\n"));
 			f->skip_count++;
 			goto check_parent;
 		}
-		DEBUG_MAIN(("main: Desc Email ID %x [d_ptr->id = %x]\n", d_ptr->desc->id, d_ptr->id));
+		LSPST_DEBUG_MAIN(("main: Desc Email ID %x [d_ptr->id = %x]\n", d_ptr->desc->id, d_ptr->id));
 
 		item = _pst_parse_item(&pstfile, d_ptr);
-		DEBUG_MAIN(("main: About to process item @ %p.\n", item));
+		LSPST_DEBUG_MAIN(("main: About to process item @ %p.\n", item));
 		if (item != NULL) {
 
 			// there should only be one message_store, and we have already
@@ -136,7 +136,7 @@
 						printf("\t%s/", item->file_as);
 				printf("\n");
 
-				DEBUG_MAIN(("main: I think I may try to go into folder \"%s\"\n", item->file_as));
+				LSPST_DEBUG_MAIN(("main: I think I may try to go into folder \"%s\"\n", item->file_as));
 				f = (struct file_ll*) malloc(sizeof(struct file_ll));
 				memset(f, 0, sizeof(struct file_ll));
 				f->next = head;
@@ -148,14 +148,14 @@
 				f->dname = (char*) xmalloc(strlen(item->file_as)+1);
 				strcpy(f->dname, item->file_as);
 
-				DEBUG_MAIN(("main: f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as));
+				LSPST_DEBUG_MAIN(("main: f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as));
 				canonicalize_filename(f->name);
 
 				if (d_ptr->child != NULL) {
 					d_ptr = d_ptr->child;
 					skip_child = 1;
 				} else {
-					DEBUG_MAIN(("main: Folder has NO children. Creating directory, and closing again\n"));
+					LSPST_DEBUG_MAIN(("main: Folder has NO children. Creating directory, and closing again\n"));
 					// printf("\tNo items to process in folder \"%s\", should have been %i\n", f->dname, f->stored_count);
 					head = f->next;
 					if (f->output != NULL)
@@ -173,13 +173,13 @@
 			} else if (item->contact != NULL) {
 				// Process Contact item {{{3
 				if (f->type != PST_TYPE_CONTACT) {
-					DEBUG_MAIN(("main: I have a contact, but the folder isn't a contacts folder. "
+					LSPST_DEBUG_MAIN(("main: I have a contact, but the folder isn't a contacts folder. "
 							 "Will process anyway\n"));
 				}
 				if (item->type != PST_TYPE_CONTACT) {
-					DEBUG_MAIN(("main: I have an item that has contact info, but doesn't say that"
+					LSPST_DEBUG_MAIN(("main: I have an item that has contact info, but doesn't say that"
 							 " it is a contact. Type is \"%s\"\n", item->ascii_type));
-					DEBUG_MAIN(("main: Processing anyway\n"));
+					LSPST_DEBUG_MAIN(("main: Processing anyway\n"));
 				}
 
 				printf("Contact");
@@ -200,7 +200,7 @@
 			} else if (item->type == PST_TYPE_JOURNAL) {
 				// Process Journal item {{{3
 				if (f->type != PST_TYPE_JOURNAL) {
-					DEBUG_MAIN(("main: I have a journal entry, but folder isn't specified as a journal type. Processing...\n"));
+					LSPST_DEBUG_MAIN(("main: I have a journal entry, but folder isn't specified as a journal type. Processing...\n"));
 				}
 
 				printf("Journal\t%s\n", rfc2426_escape(item->email->subject->subj));
@@ -209,37 +209,42 @@
 				// Process Calendar Appointment item {{{3
 				// deal with Calendar appointments
 
-				DEBUG_MAIN(("main: Processing Appointment Entry\n"));
+				LSPST_DEBUG_MAIN(("main: Processing Appointment Entry\n"));
 				if (f->type != PST_TYPE_APPOINTMENT) {
-					DEBUG_MAIN(("main: I have an appointment, but folder isn't specified as an appointment type. Processing...\n"));
+					LSPST_DEBUG_MAIN(("main: I have an appointment, but folder isn't specified as an appointment type. Processing...\n"));
 				}
 
 				printf("Appointment");
 				if (item->email != NULL && item->email->subject != NULL)
 					printf("\tSUMMARY: %s", rfc2426_escape(item->email->subject->subj));
-				if (item->appointment != NULL && item->appointment->start != NULL)
-					printf("\tSTART: %s", rfc2445_datetime_format(item->appointment->start));
+				if (item->appointment != NULL) {
+					if (item->appointment->start != NULL)
+						printf("\tSTART: %s", rfc2445_datetime_format(item->appointment->start));
+					if (item->appointment->end != NULL)
+						printf("\tEND: %s", rfc2445_datetime_format(item->appointment->end));
+					printf("\tALL DAY: %s", (item->appointment->all_day==1 ? "Yes" : "No"));
+				}
 				printf("\n");
 
 				// }}}3
 			} else {
 				f->skip_count++;
-				DEBUG_MAIN(("main: Unknown item type. %i. Ascii1=\"%s\"\n", \
+				LSPST_DEBUG_MAIN(("main: Unknown item type. %i. Ascii1=\"%s\"\n", \
 					item->type, item->ascii_type));
 			}
 		} else {
 			f->skip_count++;
-			DEBUG_MAIN(("main: A NULL item was seen\n"));
+			LSPST_DEBUG_MAIN(("main: A NULL item was seen\n"));
 		}
 
 		check_parent:
 		//	  _pst_freeItem(item);
 		while (!skip_child && d_ptr->next == NULL && d_ptr->parent != NULL) {
-			DEBUG_MAIN(("main: Going to Parent\n"));
+			LSPST_DEBUG_MAIN(("main: Going to Parent\n"));
 			head = f->next;
 			if (f->output != NULL)
 				fclose(f->output);
-			DEBUG_MAIN(("main: Email Count for folder %s is %i\n", f->dname, f->email_count));
+			LSPST_DEBUG_MAIN(("main: Email Count for folder %s is %i\n", f->dname, f->email_count));
 			/*
 			printf("\t\"%s\" - %i items done, skipped %i, should have been %i\n", \
 					f->dname, f->email_count, f->skip_count, f->stored_count);
@@ -250,7 +255,7 @@
 			free(f);
 			f = head;
 			if (head == NULL) { //we can't go higher. Must be at start?
-				DEBUG_MAIN(("main: We are now trying to go above the highest level. We must be finished\n"));
+				LSPST_DEBUG_MAIN(("main: We are now trying to go above the highest level. We must be finished\n"));
 				break; //from main while loop
 			}
 			d_ptr = d_ptr->parent;
@@ -258,7 +263,7 @@
 		}
 
 		if (item != NULL) {
-			DEBUG_MAIN(("main: Freeing memory used by item\n"));
+			LSPST_DEBUG_MAIN(("main: Freeing memory used by item\n"));
 			_pst_freeItem(item);
 			item = NULL;
 		}
@@ -268,11 +273,11 @@
 		else
 			skip_child = 0;
 
-		if (d_ptr == NULL) { DEBUG_MAIN(("main: d_ptr is now NULL\n")); }
+		if (d_ptr == NULL) { LSPST_DEBUG_MAIN(("main: d_ptr is now NULL\n")); }
 
 	// }}}2
 	} // end while(d_ptr != NULL)
-	DEBUG_MAIN(("main: Finished.\n"));
+	LSPST_DEBUG_MAIN(("main: Finished.\n"));
 
 	// Cleanup {{{2
 	pst_close(&pstfile);
--- a/src/readpst.c	Sat Feb 25 16:16:15 2006 -0800
+++ b/src/readpst.c	Tue Jul 10 17:17:28 2007 -0700
@@ -62,6 +62,7 @@
 	int32_t type;
 	struct file_ll *next;
 };
+
 void  write_email_body(FILE *f, char *body);
 char *removeCR (char *c);
 int32_t   usage();
@@ -82,10 +83,10 @@
 char *skip_header_prologue(char *headers);
 void write_separate_attachment(char f_name[], pst_item_attach* current_attach, int attach_num, pst_file* pst);
 void write_inline_attachment(FILE* f_output, pst_item_attach* current_attach, char boundary[], pst_file* pst);
-void write_normal_email(FILE* f_output, char f_name[], pst_item* item, int mode, int mode_MH, pst_file* pst);
+void write_normal_email(FILE* f_output, char f_name[], pst_item* item, int mode, int mode_MH, pst_file* pst, int save_rtf);
 void write_vcard(FILE* f_output, pst_item_contact* contact, char comment[]);
 void write_appointment(FILE* f_output, pst_item_appointment* appointment,
-		       pst_item_email* email, FILETIME* create_date, FILETIME* modify_date);
+			   pst_item_email* email, FILETIME* create_date, FILETIME* modify_date);
 void create_enter_dir(struct file_ll* f, char file_as[], int mode, int overwrite);
 char *prog_name;
 char *output_dir = ".";
@@ -135,18 +136,25 @@
 	int output_mode = OUTPUT_NORMAL;
 	int contact_mode = CMODE_VCARD;
 	int overwrite = 0;
-	//  int encrypt = 0;
-	char *temp = NULL; //temporary char pointer
-	int skip_child = 0;
-	struct file_ll  *f, *head;
+	char *enc = NULL;				 // base64 encoded attachment
+	char *boundary = NULL, *b1, *b2; // the boundary marker between multipart sections
+	char *temp = NULL;				 //temporary char pointer
+	char *attach_filename = NULL;
+	int  skip_child = 0;
+	struct file_ll	*f, *head;
+	int save_rtf_body = 1;
 	prog_name = argv[0];
 
-	while ((c = getopt(argc, argv, "d:hko:qrMSVwc:"))!= -1) {
+	// command-line option handling
+	while ((c = getopt(argc, argv, "bd:hko:qrMSVwc:"))!= -1) {
 		switch (c) {
+		case 'b':
+			save_rtf_body = 0;
+			break;
 		case 'c':
-			if (optarg!=NULL && optarg[0]=='v')
+			if (optarg && optarg[0]=='v')
 				contact_mode=CMODE_VCARD;
-			else if (optarg!=NULL && optarg[0]=='l')
+			else if (optarg && optarg[0]=='l')
 				contact_mode=CMODE_LIST;
 			else {
 				usage();
@@ -195,7 +203,7 @@
 
 #ifdef DEBUG_ALL
 	// initialize log file
-	if (d_log == NULL)
+	if (!d_log)
 		d_log = "readpst.log";
 	DEBUG_INIT(d_log);
 	DEBUG_REGISTER_CLOSE();
@@ -229,14 +237,14 @@
 	if (output_mode != OUTPUT_QUIET) printf("About to start processing first record...\n");
 
 	d_ptr = pstfile.d_head; // first record is main record
-	if ((item = _pst_parse_item(&pstfile, d_ptr)) == NULL || item->message_store == NULL) {
+	if (!(item = _pst_parse_item(&pstfile, d_ptr)) || !item->message_store) {
 		DIE(("main: Could not get root record\n"));
 	}
 
 	// default the file_as to the same as the main filename if it doesn't exist
-	if (item->file_as == NULL) {
-		if ((temp = strrchr(fname, '/')) == NULL)
-			if ((temp = strrchr(fname, '\\')) == NULL)
+	if (!item->file_as) {
+		if (!(temp = strrchr(fname, '/')))
+			if (!(temp = strrchr(fname, '\\')))
 				temp = fname;
 			else
 				temp++; // get past the "\\"
@@ -258,7 +266,7 @@
 	create_enter_dir(f, item->file_as, mode, overwrite);
 	f->type = item->type;
 
-	if ((d_ptr = pst_getTopOfFolders(&pstfile, item)) == NULL) {
+	if (!(d_ptr = pst_getTopOfFolders(&pstfile, item))) {
 		DIE(("Top of folders record not found. Cannot continue\n"));
 	}
 
@@ -267,18 +275,18 @@
 		item = NULL;
 	}
 
-	/*  if ((item = _pst_parse_item(&pstfile, d_ptr)) == NULL || item->folder == NULL) {
-	    DEBUG_MAIN(("main: Could not get \"Top Of Personal Folder\" record\n"));
-	    return -2;
-	    }*/
+	/*	if ((item = _pst_parse_item(&pstfile, d_ptr)) == NULL || item->folder == NULL) {
+		DEBUG_MAIN(("main: Could not get \"Top Of Personal Folder\" record\n"));
+		return -2;
+		}*/
 	d_ptr = d_ptr->child; // do the children of TOPF
 
 	if (output_mode != OUTPUT_QUIET) printf("Processing items...\n");
 
 	DEBUG_MAIN(("main: About to do email stuff\n"));
-	while (d_ptr != NULL) {
+	while (d_ptr) {
 		DEBUG_MAIN(("main: New item record\n"));
-		if (d_ptr->desc == NULL) {
+		if (!d_ptr->desc) {
 			DEBUG_WARN(("main: ERROR ?? item's desc record is NULL\n"));
 			f->skip_count++;
 			goto check_parent;
@@ -287,19 +295,18 @@
 
 		item = _pst_parse_item(&pstfile, d_ptr);
 		DEBUG_MAIN(("main: About to process item\n"));
-		if (item != NULL && item->email != NULL && item->email->subject != NULL &&
-		    item->email->subject->subj != NULL) {
+		if (item && item->email && item->email->subject &&
+			item->email->subject->subj) {
 			//	  DEBUG_EMAIL(("item->email->subject = %p\n", item->email->subject));
 			//	  DEBUG_EMAIL(("item->email->subject->subj = %p\n", item->email->subject->subj));
 		}
-		if (item != NULL) {
-			if (item->message_store != NULL) {
+		if (item) {
+			if (item->message_store) {
 				// there should only be one message_store, and we have already done it
 				DIE(("main: A second message_store has been found. Sorry, this must be an error.\n"));
 			}
 
-
-			if (item->folder != NULL) {
+			if (item->folder) {
 				// if this is a folder, we want to recurse into it
 				if (output_mode != OUTPUT_QUIET) printf("Processing Folder \"%s\"\n", item->file_as);
 				//	f->email_count++;
@@ -316,7 +323,7 @@
 				temp = item->file_as;
 				temp = check_filename(temp);
 				create_enter_dir(f, item->file_as, mode, overwrite);
-				if (d_ptr->child != NULL) {
+				if (d_ptr->child) {
 					d_ptr = d_ptr->child;
 					skip_child = 1;
 				} else {
@@ -324,7 +331,7 @@
 					if (output_mode != OUTPUT_QUIET)
 						printf("\tNo items to process in folder \"%s\", should have been %i\n", f->dname, f->stored_count);
 					head = f->next;
-					if (f->output != NULL)
+					if (f->output)
 						fclose(f->output);
 					if (mode == MODE_KMAIL)
 						close_kmail_dir();
@@ -341,7 +348,7 @@
 				_pst_freeItem(item);
 				item = NULL; // just for the odd situations!
 				goto check_parent;
-			} else if (item->contact != NULL) {
+			} else if (item->contact) {
 				// deal with a contact
 				// write them to the file, one per line in this format
 				// Desc Name <email@address>\n
@@ -353,14 +360,14 @@
 				DEBUG_MAIN(("main: Processing Contact\n"));
 				if (f->type != PST_TYPE_CONTACT) {
 					DEBUG_MAIN(("main: I have a contact, but the folder isn't a contacts folder. "
-						    "Will process anyway\n"));
+							"Will process anyway\n"));
 				}
 				if (item->type != PST_TYPE_CONTACT) {
 					DEBUG_MAIN(("main: I have an item that has contact info, but doesn't say that"
-						    " it is a contact. Type is \"%s\"\n", item->ascii_type));
+							" it is a contact. Type is \"%s\"\n", item->ascii_type));
 					DEBUG_MAIN(("main: Processing anyway\n"));
 				}
-				if (item->contact == NULL) { // this is an incorrect situation. Inform user
+				if (!item->contact) { // this is an incorrect situation. Inform user
 					DEBUG_MAIN(("main: ERROR. This contact has not been fully parsed. one of the pre-requisties is NULL\n"));
 				} else {
 					if (contact_mode == CMODE_VCARD)
@@ -368,8 +375,7 @@
 					else
 						fprintf(f->output, "%s <%s>\n", item->contact->fullname, item->contact->address1);
 				}
-			} else if (item->email != NULL &&
-				   (item->type == PST_TYPE_NOTE || item->type == PST_TYPE_REPORT)) {
+			} else if (item->email && (item->type == PST_TYPE_NOTE || item->type == PST_TYPE_REPORT)) {
 				if (mode == MODE_SEPERATE) {
 					mk_seperate_file(f);
 				}
@@ -377,7 +383,7 @@
 				f->email_count++;
 
 				DEBUG_MAIN(("main: seen an email\n"));
-				write_normal_email(f->output, f->name, item, mode, mode_MH, &pstfile);
+				write_normal_email(f->output, f->name, item, mode, mode_MH, &pstfile, save_rtf_body);
 			} else if (item->type == PST_TYPE_JOURNAL) {
 				// deal with journal items
 				if (mode == MODE_SEPERATE) {
@@ -395,11 +401,11 @@
 					item->ascii_type));
 					}*/
 				fprintf(f->output, "BEGIN:VJOURNAL\n");
-				if (item->email->subject != NULL)
+				if (item->email->subject)
 					fprintf(f->output, "SUMMARY:%s\n", rfc2426_escape(item->email->subject->subj));
-				if (item->email->body != NULL)
+				if (item->email->body)
 					fprintf(f->output, "DESCRIPTION:%s\n", rfc2426_escape(item->email->body));
-				if (item->journal->start != NULL)
+				if (item->journal->start)
 					fprintf(f->output, "DTSTART;VALUE=DATE-TIME:%s\n", rfc2445_datetime_format(item->journal->start));
 				fprintf(f->output, "END:VJOURNAL\n\n");
 			} else if (item->type == PST_TYPE_APPOINTMENT) {
@@ -417,7 +423,7 @@
 			} else {
 				f->skip_count++;
 				DEBUG_MAIN(("main: Unknown item type. %i. Ascii1=\"%s\"\n",
-					    item->type, item->ascii_type));
+						item->type, item->ascii_type));
 			}
 		} else {
 			f->skip_count++;
@@ -428,15 +434,15 @@
 
 	check_parent:
 		//	  _pst_freeItem(item);
-		while (!skip_child && d_ptr->next == NULL && d_ptr->parent != NULL) {
+		while (!skip_child && !d_ptr->next && d_ptr->parent) {
 			DEBUG_MAIN(("main: Going to Parent\n"));
 			head = f->next;
-			if (f->output != NULL)
+			if (f->output)
 				fclose(f->output);
 			DEBUG_MAIN(("main: Email Count for folder %s is %i\n", f->dname, f->email_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);
+					   f->dname, f->email_count, f->skip_count, f->stored_count);
 			if (mode == MODE_KMAIL)
 				close_kmail_dir();
 			else if (mode == MODE_RECURSE)
@@ -447,7 +453,7 @@
 			free(f->dname);
 			free(f);
 			f = head;
-			if (head == NULL) { //we can't go higher. Must be at start?
+			if (!head) { //we can't go higher. Must be at start?
 				DEBUG_MAIN(("main: We are now trying to go above the highest level. We must be finished\n"));
 				break; //from main while loop
 			}
@@ -455,7 +461,7 @@
 			skip_child = 0;
 		}
 
-		if (item != NULL) {
+		if (item) {
 			DEBUG_MAIN(("main: Freeing memory used by item\n"));
 			_pst_freeItem(item);
 			item = NULL;
@@ -466,7 +472,7 @@
 		else
 			skip_child = 0;
 
-		if (d_ptr == NULL) {
+		if (!d_ptr) {
 			DEBUG_MAIN(("main: d_ptr is now NULL\n"));
 		}
 	}
@@ -474,9 +480,9 @@
 	DEBUG_MAIN(("main: Finished.\n"));
 
 	pst_close(&pstfile);
-	//  fclose(pstfile.fp);
-	while (f != NULL) {
-		if (f->output != NULL)
+	//	fclose(pstfile.fp);
+	while (f) {
+		if (f->output)
 			fclose(f->output);
 		free(f->name);
 		free(f->dname);
@@ -497,11 +503,13 @@
 
 	return 0;
 }
+
+
 void write_email_body(FILE *f, char *body) {
 	char *n = body;
-	//  DEBUG_MAIN(("write_email_body(): \"%s\"\n", body));
+	//	DEBUG_MAIN(("write_email_body(): \"%s\"\n", body));
 	DEBUG_ENT("write_email_body");
-	while (n != NULL) {
+	while (n) {
 		if (strncmp(body, "From ", 5) == 0)
 			fprintf(f, ">");
 		if ((n = strchr(body, '\n'))) {
@@ -514,6 +522,8 @@
 	fwrite(body, strlen(body), 1, f);
 	DEBUG_RET();
 }
+
+
 char *removeCR (char *c) {
 	// converts /r/n to /n
 	char *a, *b;
@@ -529,17 +539,20 @@
 	DEBUG_RET();
 	return c;
 }
+
+
 int usage() {
 	DEBUG_ENT("usage");
 	version();
 	printf("Usage: %s [OPTIONS] {PST FILENAME}\n", prog_name);
 	printf("OPTIONS:\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-d\t- Debug to file. This is a binary log. Use readlog to print it\n");
+	printf("\t-d <filename> \t- Debug to file. This is a binary log. Use readlog to print it\n");
 	printf("\t-h\t- Help. This screen\n");
 	printf("\t-k\t- KMail. Output in kmail format\n");
 	printf("\t-M\t- MH. Write emails in the MH format\n");
-	printf("\t-o\t- Output Dir. Directory to write files to. CWD is changed *after* opening pst file\n");
+	printf("\t-o <dirname>\t- Output Dir. 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-S\t- Seperate. Write emails in the seperate format\n");
@@ -548,6 +561,8 @@
 	DEBUG_RET();
 	return 0;
 }
+
+
 int version() {
 	DEBUG_ENT("version");
 	printf("ReadPST v%s\n", VERSION);
@@ -564,6 +579,8 @@
 	DEBUG_RET();
 	return 0;
 }
+
+
 char *mk_kmail_dir(char *fname) {
 	//change to that directory
 	//make a directory based on OUTPUT_KMAIL_DIR_TEMPLATE
@@ -572,7 +589,7 @@
 	char *dir, *out_name, *index;
 	int x;
 	DEBUG_ENT("mk_kmail_dir");
-	if (kmail_chdir != NULL && chdir(kmail_chdir)) {
+	if (kmail_chdir && chdir(kmail_chdir)) {
 		x = errno;
 		DIE(("mk_kmail_dir: Cannot change to directory %s: %s\n", kmail_chdir, strerror(x)));
 	}
@@ -601,11 +618,13 @@
 	DEBUG_RET();
 	return out_name;
 }
+
+
 int close_kmail_dir() {
 	// change ..
 	int x;
 	DEBUG_ENT("close_kmail_dir");
-	if (kmail_chdir != NULL) { //only free kmail_chdir if not NULL. do not change directory
+	if (kmail_chdir) { //only free kmail_chdir if not NULL. do not change directory
 		free(kmail_chdir);
 		kmail_chdir = NULL;
 	} else {
@@ -617,6 +636,8 @@
 	DEBUG_RET();
 	return 0;
 }
+
+
 // this will create a directory by that name, then make an mbox file inside
 // that dir.  any subsequent dirs will be created by name, and they will
 // contain mbox files
@@ -640,6 +661,8 @@
 	DEBUG_RET();
 	return out_name;
 }
+
+
 int close_recurse_dir() {
 	int x;
 	DEBUG_ENT("close_recurse_dir");
@@ -650,16 +673,18 @@
 	DEBUG_RET();
 	return 0;
 }
+
+
 char *mk_seperate_dir(char *dir, int overwrite) {
-#if !defined(WIN32) && !defined(__CYGWIN__)
-	DIR * sdir = NULL;
-	struct dirent *dirent = NULL;
-	struct stat *filestat = xmalloc(sizeof(struct stat));
-#endif
+	DEBUG_ENT("mk_seperate_dir");
+	#if !defined(WIN32) && !defined(__CYGWIN__)
+		DIR * sdir = NULL;
+		struct dirent *dirent = NULL;
+		struct stat *filestat = xmalloc(sizeof(struct stat));
+	#endif
 
 	char *dir_name = NULL;
 	int x = 0, y = 0;
-	DEBUG_ENT("mk_seperate_dir");
 	/*#if defined(WIN32) || defined(__CYGWIN__)
 	  DIE(("mk_seperate_dir: Win32 applications cannot use this function yet.\n"));
 	  #endif*/
@@ -673,7 +698,7 @@
 			sprintf(dir_name, "%s" SEP_MAIL_FILE_TEMPLATE, dir, y); // enough for 9 digits allocated above
 
 		dir_name = check_filename(dir_name);
-		DEBUG_MAIN(("mk_seperate_dir: about to try creating %s\n", dir_name));
+		DEBUG_MAIN(("about to try creating %s\n", dir_name));
 		if (D_MKDIR(dir_name)) {
 			if (errno != EEXIST) { // if there is an error, and it doesn't already exist
 				x = errno;
@@ -693,10 +718,10 @@
 	if (overwrite) {
 		// we should probably delete all files from this directory
 #if !defined(WIN32) && !defined(__CYGWIN__)
-		if ((sdir = opendir("./")) == NULL) {
+		if (!(sdir = opendir("./"))) {
 			WARN(("mk_seperate_dir: Cannot open dir \"%s\" for deletion of old contents\n", "./"));
 		} else {
-			while ((dirent = readdir(sdir)) != NULL) {
+			while ((dirent = readdir(sdir))) {
 				if (lstat(dirent->d_name, filestat) != -1)
 					if (S_ISREG(filestat->st_mode)) {
 						if (unlink(dirent->d_name)) {
@@ -710,12 +735,14 @@
 	}
 
 	// overwrite will never change during this function, it is just there so that
-	//  if overwrite is set, we only go through this loop once.
+	//	if overwrite is set, we only go through this loop once.
 
 	// we don't return a filename here cause it isn't necessary.
 	DEBUG_RET();
 	return NULL;
 }
+
+
 int close_seperate_dir() {
 	int x;
 	DEBUG_ENT("close_seperate_dir");
@@ -726,35 +753,39 @@
 	DEBUG_RET();
 	return 0;
 }
+
+
 int mk_seperate_file(struct file_ll *f) {
 	const int name_offset = 1;
 	DEBUG_ENT("mk_seperate_file");
-	DEBUG_MAIN(("mk_seperate_file: opening next file to save email\n"));
+	DEBUG_MAIN(("opening next file to save email\n"));
 	if (f->email_count > 999999999) { // bigger than nine 9's
 		DIE(("mk_seperate_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);
-	if (f->output != NULL)
+	if (f->output)
 		fclose(f->output);
 	f->output = NULL;
 	f->name = check_filename(f->name);
-	if ((f->output = fopen(f->name, "w")) == NULL) {
+	if (!(f->output = fopen(f->name, "w"))) {
 		DIE(("mk_seperate_file: Cannot open file to save email \"%s\"\n", f->name));
 	}
 	DEBUG_RET();
 	return 0;
 }
+
+
 char *my_stristr(char *haystack, char *needle) {
-// my_stristr varies from strstr in that its searches are case-insensitive
+	// my_stristr varies from strstr in that its searches are case-insensitive
 	char *x=haystack, *y=needle, *z = NULL;
 	DEBUG_ENT("my_stristr");
-	if (haystack == NULL || needle == NULL)
+	if (!haystack || !needle)
 		return NULL;
 	while (*y != '\0' && *x != '\0') {
 		if (tolower(*y) == tolower(*x)) {
 			// move y on one
 			y++;
-			if (z == NULL) {
+			if (!z) {
 				z = x; // store first position in haystack where a match is made
 			}
 		} else {
@@ -766,49 +797,61 @@
 	DEBUG_RET();
 	return z;
 }
+
+
 char *check_filename(char *fname) {
 	char *t = fname;
 	DEBUG_ENT("check_filename");
-	if (t == NULL) {
+	if (!t) {
 		DEBUG_RET();
 		return fname;
 	}
-	while ((t = strpbrk(t, "/\\:")) != NULL) {
+	while ((t = strpbrk(t, "/\\:"))) {
 		// while there are characters in the second string that we don't want
 		*t = '_'; //replace them with an underscore
 	}
 	DEBUG_RET();
 	return fname;
 }
+
+
 char *rfc2426_escape(char *str) {
 	static char* buf = NULL;
 	char *ret, *a, *b;
 	int x = 0, y, z;
 	DEBUG_ENT("rfc2426_escape");
-	if (str == NULL)
+	if (!str)
 		ret = str;
 	else {
 
 		// calculate space required to escape all the following characters
-		x = strlen(str) +(y=(chr_count(str, ',')*2) + (chr_count(str, '\\')*2) + (chr_count(str, ';')*2) + (chr_count(str, '\n')*2));
+		y = chr_count(str, ',')
+		  + chr_count(str, '\\')
+		  + chr_count(str, ';')
+		  + chr_count(str, '\n');
 		z = chr_count(str, '\r');
+		x = strlen(str) + y - z + 1; // don't forget room for the NUL
 		if (y == 0 && z == 0)
 			// there isn't any extra space required
 			ret = str;
 		else {
-			buf = (char*) realloc(buf, x+1);
+			buf = (char*) realloc(buf, x);
 			a = str;
 			b = buf;
 			while (*a != '\0') {
-				switch(*a) {
+				switch (*a) {
 				case ',' :
 				case '\\':
 				case ';' :
-				case '\n':
-					*(b++)='\\';
-					*b=*a;
+					*(b++) = '\\';
+					*b = *a;
 					break;
-				case '\r':
+				case '\n':  // newlines are encoded as "\n"
+					*(b++) = '\\';
+					*b = 'n';
+					break;
+				case '\r':  // skip cr
+					b--;
 					break;
 				default:
 					*b=*a;
@@ -816,13 +859,15 @@
 				b++;
 				a++;
 			}
-			*b = '\0';
+			*b = '\0'; // NUL-terminate the string (buf)
 			ret = buf;
 		}
 	}
 	DEBUG_RET();
 	return ret;
 }
+
+
 int chr_count(char *str, char x) {
 	int r = 0;
 	while (*str != '\0') {
@@ -832,11 +877,13 @@
 	}
 	return r;
 }
+
+
 char *rfc2425_datetime_format(FILETIME *ft) {
 	static char * buffer = NULL;
 	struct tm *stm = NULL;
 	DEBUG_ENT("rfc2425_datetime_format");
-	if (buffer == NULL)
+	if (!buffer)
 		buffer = malloc(30); // should be enough for the date as defined below
 
 	stm = fileTimeToStructTM(ft);
@@ -847,11 +894,13 @@
 	DEBUG_RET();
 	return buffer;
 }
+
+
 char *rfc2445_datetime_format(FILETIME *ft) {
 	static char* buffer = NULL;
 	struct tm *stm = NULL;
 	DEBUG_ENT("rfc2445_datetime_format");
-	if (buffer == NULL)
+	if (!buffer)
 		buffer = malloc(30); // should be enough
 	stm = fileTimeToStructTM(ft);
 	if (strftime(buffer, 30, "%Y%m%dT%H%M%SZ", stm)==0) {
@@ -860,110 +909,131 @@
 	DEBUG_RET();
 	return buffer;
 }
+
+
 // The sole purpose of this function is to bypass the pseudo-header prologue
 // that Microsoft Outlook inserts at the beginning of the internet email
 // headers for emails stored in their "Personal Folders" files.
 char *skip_header_prologue(char *headers) {
 	const char *bad = "Microsoft Mail Internet Headers";
-
 	if ( strncmp(headers, bad, strlen(bad)) == 0 ) {
 		// Found the offensive header prologue
-		char *pc;
-
-		pc = strchr(headers, '\n');
+		char *pc = strchr(headers, '\n');
 		return pc + 1;
 	}
-
 	return headers;
 }
 
-// vim:sw=4 ts=4:
-// vim600: set foldlevel=0 foldmethod=marker:
+
 void write_separate_attachment(char f_name[], pst_item_attach* current_attach, int attach_num, pst_file* pst)
 {
+	DEBUG_ENT("write_separate_attachment");
 	FILE *fp = NULL;
 	int x = 0;
-	char *temp;
+	char *temp = NULL;
+
+	// If there is a long filename (filename2) use that, otherwise
+	// use the 8.3 filename (filename1)
+	char *attach_filename = (current_attach->filename2) ? current_attach->filename2
+														: current_attach->filename1;
 
 	check_filename(f_name);
-	if (current_attach->filename2 == NULL) {
+	if (!attach_filename) {
+		// generate our own (dummy) filename for the attachement
 		temp = xmalloc(strlen(f_name)+15);
 		sprintf(temp, "%s-attach%i", f_name, attach_num);
 	} else {
-		temp = xmalloc(strlen(f_name)+strlen(current_attach->filename2)+15);
+		// have an attachment name, make sure it's unique
+		temp = xmalloc(strlen(f_name)+strlen(attach_filename)+15);
 		do {
-			if (fp != NULL) fclose(fp);
+			if (fp) fclose(fp);
 			if (x == 0)
-				sprintf(temp, "%s-%s", f_name, current_attach->filename2);
+				sprintf(temp, "%s-%s", f_name, attach_filename);
 			else
-				sprintf(temp, "%s-%s-%i", f_name, current_attach->filename2, x);
-		} while ((fp = fopen(temp, "r"))!=NULL && ++x < 99999999);
+				sprintf(temp, "%s-%s-%i", f_name, attach_filename, x);
+		} while ((fp = fopen(temp, "r")) && ++x < 99999999);
 		if (x > 99999999) {
 			DIE(("error finding attachment name. exhausted possibilities to %s\n", temp));
 		}
 	}
-	DEBUG_MAIN(("write_separate_attachment: Saving attachment to %s\n", temp));
-	if ((fp = fopen(temp, "w")) == NULL) {
+	DEBUG_EMAIL(("Saving attachment to %s\n", temp));
+	if (!(fp = fopen(temp, "w"))) {
 		WARN(("write_separate_attachment: Cannot open attachment save file \"%s\"\n", temp));
 	} else {
-		if (current_attach->data != NULL)
+		if (current_attach->data)
 			fwrite(current_attach->data, 1, current_attach->size, fp);
 		else {
 			pst_attach_to_file(pst, current_attach, fp);
 		}
 		fclose(fp);
 	}
+	if (temp) free(temp);
+	DEBUG_RET();
 }
 
+
 void write_inline_attachment(FILE* f_output, pst_item_attach* current_attach, char boundary[], pst_file* pst)
 {
+	DEBUG_ENT("write_inline_attachment");
 	char *enc; // base64 encoded attachment
-       DEBUG_MAIN(("write_inline_attachment: Attachment Size is %i\n", current_attach->size));
-       DEBUG_MAIN(("write_inline_attachment: Attachment Pointer is %p\n", current_attach->data));
-	if (current_attach->data != NULL) {
-		if ((enc = base64_encode (current_attach->data, current_attach->size)) == NULL) {
-			DEBUG_MAIN(("write_inline_attachment: ERROR base64_encode returned NULL. Must have failed\n"));
+	DEBUG_EMAIL(("Attachment Size is %i\n", current_attach->size));
+	DEBUG_EMAIL(("Attachment Pointer is %p\n", current_attach->data));
+	if (current_attach->data) {
+		enc = base64_encode (current_attach->data, current_attach->size);
+		if (!enc) {
+			DEBUG_EMAIL(("ERROR base64_encode returned NULL. Must have failed\n"));
 			return;
 		}
 	}
 	if (boundary) {
+		char *attach_filename;
 		fprintf(f_output, "\n--%s\n", boundary);
-		if (current_attach->mimetype == NULL) {
+		if (!current_attach->mimetype) {
 			fprintf(f_output, "Content-type: %s\n", MIME_TYPE_DEFAULT);
 		} else {
 			fprintf(f_output, "Content-type: %s\n", current_attach->mimetype);
 		}
 		fprintf(f_output, "Content-transfer-encoding: base64\n");
-		if (current_attach->filename2 == NULL) {
+		// If there is a long filename (filename2) use that, otherwise
+		// use the 8.3 filename (filename1)
+		if (current_attach->filename2) {
+		  attach_filename = current_attach->filename2;
+		} else {
+		  attach_filename = current_attach->filename1;
+		}
+		if (!attach_filename) {
 			fprintf(f_output, "Content-Disposition: inline\n\n");
 		} else {
-			fprintf(f_output, "Content-Disposition: attachment; filename=\"%s\"\n\n",
-				current_attach->filename2);
+			fprintf(f_output, "Content-Disposition: attachment; filename=\"%s\"\n\n", attach_filename);
 		}
 	}
-	if (current_attach->data != NULL) {
+	if (current_attach->data) {
 		fwrite(enc, 1, strlen(enc), f_output);
-		DEBUG_MAIN(("Attachment Size after encoding is %i\n", strlen(enc)));
+		DEBUG_EMAIL(("Attachment Size after encoding is %i\n", strlen(enc)));
 	} else {
 		pst_attach_to_file_base64(pst, current_attach, f_output);
 	}
 	fprintf(f_output, "\n\n");
+	DEBUG_RET();
 }
 
-void write_normal_email(FILE* f_output, char f_name[], pst_item* item, int mode, int mode_MH, pst_file* pst)
+
+void write_normal_email(FILE* f_output, char f_name[], pst_item* item, int mode, int mode_MH, pst_file* pst, int save_rtf)
 {
-	char *boundary = NULL; // the boundary marker between multipart sections
+	DEBUG_ENT("write_normal_email");
+	char *boundary = NULL;		// the boundary marker between multipart sections
+	int boundary_created = 0;	// we have not (yet) created a new boundary
 	char *temp = NULL;
 	int attach_num, base64_body = 0;
 	time_t em_time;
 	char *c_time;
-       pst_item_attach* current_attach;
+	pst_item_attach* current_attach;
 
 	// convert the sent date if it exists, or set it to a fixed date
-	if (item->email->sent_date != NULL) {
+	if (item->email->sent_date) {
 		em_time = fileTimeToUnixTime(item->email->sent_date, 0);
 		c_time = ctime(&em_time);
-		if (c_time != NULL)
+		if (c_time)
 			c_time[strlen(c_time)-1] = '\0'; //remove end \n
 		else
 			c_time = "Fri Dec 28 12:06:21 2001";
@@ -971,19 +1041,20 @@
 		c_time= "Fri Dec 28 12:06:21 2001";
 
 	// we will always look at the header to discover some stuff
-	if (item->email->header != NULL ) {
+	if (item->email->header ) {
 		char *b1, *b2;
 		// see if there is a boundary variable there
 		// this search MUST be made case insensitive (DONE).
-		// Also, some check to find out if we
-		// are looking at the boundary associated with content-type, and that the content
-		// type really is "multipart"
+		// Also, we should check to find out if we are looking
+		// at the boundary associated with content-type, and that
+		// the content type really is multipart
 
 		removeCR(item->email->header);
 
-		if ((b2 = my_stristr(item->email->header, "boundary=")) != NULL) {
+		if ((b2 = my_stristr(item->email->header, "boundary="))) {
+			int len;
 			b2 += strlen("boundary="); // move boundary to first char of marker
-	    
+
 			if (*b2 == '"') {
 				b2++;
 				b1 = strchr(b2, '"'); // find terminating quote
@@ -992,10 +1063,10 @@
 				while (isgraph(*b1)) // find first char that isn't part of boundary
 					b1++;
 			}
-	    
-			boundary = malloc ((b1-b2)+1); //malloc that length
-			memset (boundary, 0, (b1-b2)+1);  // blank it
-			strncpy(boundary, b2, b1-b2); // copy boundary to another variable
+			len = b1 - b2;
+			boundary = malloc(len+1);	//malloc that length
+			strncpy(boundary, b2, len); // copy boundary to another variable
+			boundary[len] = '\0';
 			b1 = b2 = boundary;
 			while (*b2 != '\0') { // remove any CRs and Tabs
 				if (*b2 != '\n' && *b2 != '\r' && *b2 != '\t') {
@@ -1005,379 +1076,378 @@
 				b2++;
 			}
 			*b1 = '\0';
-	    
-			DEBUG_MAIN(("write_normal_email: Found boundary of - %s\n", boundary));
+
+			DEBUG_EMAIL(("Found boundary of - %s\n", boundary));
 		} else {
-			DEBUG_MAIN(("write_normal_email: boundary not found in header\n"));
+			DEBUG_EMAIL(("boundary not found in header\n"));
 		}
 
 		// also possible to set 7bit encoding detection here.
-		if ((b2 = my_stristr(item->email->header, "Content-Transfer-Encoding:")) != NULL) {
-			if ((b2 = strchr(b2, ':')) != NULL) {
+		if ((b2 = my_stristr(item->email->header, "Content-Transfer-Encoding:"))) {
+			if ((b2 = strchr(b2, ':'))) {
 				b2++; // skip to the : at the end of the string
-		
+
 				while (*b2 == ' ' || *b2 == '\t')
 					b2++;
 				if (pst_strincmp(b2, "base64", 6)==0) {
-					DEBUG_MAIN(("body is base64 encoded\n"));
+					DEBUG_EMAIL(("body is base64 encoded\n"));
 					base64_body = 1;
 				}
 			} else {
 				DEBUG_WARN(("found a ':' during the my_stristr, but not after that..\n"));
 			}
 		}
-	    
 	}
 
-	DEBUG_MAIN(("write_normal_email: About to print Header\n"));
-
-	if (item != NULL && item->email != NULL && item->email->subject != NULL &&
-	    item->email->subject->subj != NULL) {
-		DEBUG_EMAIL(("item->email->subject->subj = %p\n", item->email->subject->subj));
+	if (!boundary && (item->attach || (item->email->body && item->email->htmlbody)
+				 || item->email->rtf_compressed || item->email->encrypted_body
+				 || item->email->encrypted_htmlbody)) {
+	  // we need to create a boundary here.
+	  DEBUG_EMAIL(("must create own boundary. oh dear.\n"));
+	  boundary = malloc(50 * sizeof(char)); // allow 50 chars for boundary
+	  boundary[0] = '\0';
+	  sprintf(boundary, "--boundary-LibPST-iamunique-%i_-_-", rand());
+	  DEBUG_EMAIL(("created boundary is %s\n", boundary));
+	  boundary_created = 1;
 	}
 
-	if (item->email->header != NULL) {
+	DEBUG_EMAIL(("About to print Header\n"));
+
+	if (item && item->email && item->email->subject && item->email->subject->subj) {
+		DEBUG_EMAIL(("item->email->subject->subj = %s\n", item->email->subject->subj));
+	}
+
+	if (item->email->header) {
+		int len;
+		char *soh = NULL;  // real start of headers.
+
 		// some of the headers we get from the file are not properly defined.
 		// they can contain some email stuff too. We will cut off the header
 		// when we see a \n\n or \r\n\r\n
+		removeCR(item->email->header);
 		temp = strstr(item->email->header, "\n\n");
 
-		if (temp != NULL) {
-			DEBUG_MAIN(("write_normal_email: Found body text in header\n"));
-			*temp = '\0';
-		} else {
-			temp = item->email->header + strlen(item->email->header) - 1;
-			if(*temp == '\n')
-				*temp = '\0';
+		if (temp) {
+			DEBUG_EMAIL(("Found body text in header\n"));
+			temp[1] = '\0'; // stop after first \n
 		}
-	  
+
+		// Now, write out the header...
+		soh = skip_header_prologue(item->email->header);
 		if (mode != MODE_SEPERATE) {
-			char *soh = NULL;  // real start of headers.
 			// don't put rubbish in if we are doing seperate
-			fprintf(f_output, "From \"%s\" %s\n", item->email->outlook_sender_name, c_time);
-			soh = skip_header_prologue(item->email->header);
-			fprintf(f_output, "%s\n", soh);
-		} else {
-			fprintf(f_output, "%s\n", item->email->header);
+			if (strncmp(soh, "X-From_: ", 9) == 0 ) {
+				fputs("From ", f_output);
+				soh += 9;
+			} else
+				fprintf(f_output, "From \"%s\" %s\n", item->email->outlook_sender_name, c_time);
 		}
+		fprintf(f_output, "%s", soh);
+		len = strlen(soh);
+		if (!len || (soh[len-1] != '\n')) fprintf(f_output, "\n");
+
 	} else {
 		//make up our own header!
 		if (mode != MODE_SEPERATE) {
 			// don't want this first line for this mode
-			if (item->email->outlook_sender_name != NULL) {
+			if (item->email->outlook_sender_name) {
 				temp = item->email->outlook_sender_name;
 			} else {
 				temp = "(readpst_null)";
 			}
 			fprintf(f_output, "From \"%s\" %s\n", temp, c_time);
 		}
-		if ((temp = item->email->outlook_sender) == NULL)
-			temp = "";
+
+		temp = item->email->outlook_sender;
+		if (!temp) temp = "";
 		fprintf(f_output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name, temp);
-		if (item->email->subject != NULL) {
+
+		if (item->email->subject) {
 			fprintf(f_output, "Subject: %s\n", item->email->subject->subj);
 		} else {
 			fprintf(f_output, "Subject: \n");
 		}
+
 		fprintf(f_output, "To: %s\n", item->email->sentto_address);
-		if (item->email->cc_address != NULL) {
+		if (item->email->cc_address) {
 			fprintf(f_output, "Cc: %s\n", item->email->cc_address);
 		}
-		if (item->email->sent_date != NULL) {
+
+		if (item->email->sent_date) {
 			c_time = (char*) xmalloc(C_TIME_SIZE);
 			strftime(c_time, C_TIME_SIZE, "%a, %d %b %Y %H:%M:%S %z", gmtime(&em_time));
 			fprintf(f_output, "Date: %s\n", c_time);
 			free(c_time);
 		}
-
-		fprintf(f_output, "MIME-Version: 1.0\n");
 	}
 
-	if (boundary == NULL && (item->attach ||(item->email->body && item->email->htmlbody)
-				 || item->email->rtf_compressed || item->email->encrypted_body
-				 || item->email->encrypted_htmlbody)) {
-		// we need to create a boundary here.
-		DEBUG_EMAIL(("write_normal_email: must create own boundary. oh dear.\n"));
-		boundary = malloc(50 * sizeof(char)); // allow 50 chars for boundary
-		boundary[0] = '\0';
-		sprintf(boundary, "--boundary-LibPST-iamunique-%i_-_-", rand());
-		DEBUG_EMAIL(("write_normal_email: created boundary is %s\n", boundary));
-
-		/* If boundary != NULL, then it has already been printed with existing
-		 * headers.  Otherwise we generate it here and print it.
-		 */
-		if (item->attach != NULL) {
+	fprintf(f_output, "MIME-Version: 1.0\n");
+	if (boundary && boundary_created) {
+		// if we created the boundary, then it has NOT already been printed
+		// in the headers above.
+		if (item->attach) {
 			// write the boundary stuff if we have attachments
-			fprintf(f_output, "Content-type: multipart/mixed;\n\tboundary=\"%s\"\n",
-				boundary);
-		} else if (boundary != NULL) {
+			fprintf(f_output, "Content-type: multipart/mixed;\n\tboundary=\"%s\"\n", boundary);
+		} else if (boundary) {
 			// else if we have multipart/alternative then tell it so
-			fprintf(f_output, "Content-type: multipart/alternative;\n\tboundary=\"%s\"\n",
-				boundary);
+			fprintf(f_output, "Content-type: multipart/alternative;\n\tboundary=\"%s\"\n", boundary);
 		} else if (item->email->htmlbody) {
 			fprintf(f_output, "Content-type: text/html\n");
 		}
 	}
-
-	fprintf(f_output, "\n");
+	fprintf(f_output, "\n");    // start the body
+	DEBUG_EMAIL(("About to print Body\n"));
 
-	DEBUG_MAIN(("write_normal_email: About to print Body\n"));
-
-	if (item->email->body != NULL) {
+	if (item->email->body) {
 		if (boundary) {
 			fprintf(f_output, "\n--%s\n", boundary);
-			fprintf(f_output, "Content-type: text/plain\n\n");
+			fprintf(f_output, "Content-type: text/plain\n");
 			if (base64_body)
 				fprintf(f_output, "Content-Transfer-Encoding: base64\n");
+			fprintf(f_output, "\n");
 		}
 		removeCR(item->email->body);
 		if (base64_body)
-			write_email_body(f_output, base64_encode(item->email->body,
-								 strlen(item->email->body)));
+			write_email_body(f_output, base64_encode(item->email->body, strlen(item->email->body)));
 		else
 			write_email_body(f_output, item->email->body);
 	}
-	
-	if (item->email->htmlbody != NULL) {
+
+	if (item->email->htmlbody) {
 		if (boundary) {
 			fprintf(f_output, "\n--%s\n", boundary);
-			fprintf(f_output, "Content-type: text/html\n\n");
+			fprintf(f_output, "Content-type: text/html\n");
 			if (base64_body)
 				fprintf(f_output, "Content-Transfer-Encoding: base64\n");
+			fprintf(f_output, "\n");
 		}
 		removeCR(item->email->htmlbody);
 		if (base64_body)
-			write_email_body(f_output, base64_encode(item->email->htmlbody,
-								 strlen(item->email->htmlbody)));
+			write_email_body(f_output, base64_encode(item->email->htmlbody, strlen(item->email->htmlbody)));
 		else
 			write_email_body(f_output, item->email->htmlbody);
 	}
 
-	if (item->email->rtf_compressed != NULL) {
-		DEBUG_MAIN(("Adding RTF body as attachment\n"));
-               current_attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach));
-               memset(current_attach, 0, sizeof(pst_item_attach));
-               current_attach->next = item->attach;
-               item->attach = current_attach;
-               current_attach->data = lzfu_decompress(item->email->rtf_compressed);
-               current_attach->filename2 = xmalloc(strlen(RTF_ATTACH_NAME)+2);
-               strcpy(current_attach->filename2, RTF_ATTACH_NAME);
-               current_attach->mimetype = xmalloc(strlen(RTF_ATTACH_TYPE)+2);
-               strcpy(current_attach->mimetype, RTF_ATTACH_TYPE);
-               memcpy(&(current_attach->size), item->email->rtf_compressed+sizeof(int32_t), sizeof(int32_t));
-               LE32_CPU(current_attach->size);
-		//	  item->email->rtf_compressed = ;
-		//	  attach_num++;
+	if (item->email->rtf_compressed && save_rtf) {
+		DEBUG_EMAIL(("Adding RTF body as attachment\n"));
+		current_attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach));
+		memset(current_attach, 0, sizeof(pst_item_attach));
+		current_attach->next = item->attach;
+		item->attach = current_attach;
+		current_attach->data = lzfu_decompress(item->email->rtf_compressed);
+		current_attach->filename2 = xmalloc(strlen(RTF_ATTACH_NAME)+2);
+		strcpy(current_attach->filename2, RTF_ATTACH_NAME);
+		current_attach->mimetype = xmalloc(strlen(RTF_ATTACH_TYPE)+2);
+		strcpy(current_attach->mimetype, RTF_ATTACH_TYPE);
+		memcpy(&(current_attach->size), item->email->rtf_compressed+sizeof(int32_t), sizeof(int32_t));
+		LE32_CPU(current_attach->size);
 	}
+
 	if (item->email->encrypted_body || item->email->encrypted_htmlbody) {
 		// if either the body or htmlbody is encrypted, add them as attachments
 		if (item->email->encrypted_body) {
-			DEBUG_MAIN(("Adding Encrypted Body as attachment\n"));
-                       current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach));
-                       memset(current_attach, 0, sizeof(pst_item_attach));
-                       current_attach->next = item->attach;
-                       item->attach = current_attach;
-	    
-                       current_attach->data = item->email->encrypted_body;
-                       current_attach->size = item->email->encrypted_body_size;
+			DEBUG_EMAIL(("Adding Encrypted Body as attachment\n"));
+			current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach));
+			memset(current_attach, 0, sizeof(pst_item_attach));
+			current_attach->next = item->attach;
+			item->attach = current_attach;
+			current_attach->data = item->email->encrypted_body;
+			current_attach->size = item->email->encrypted_body_size;
 			item->email->encrypted_body = NULL;
 		}
+
 		if (item->email->encrypted_htmlbody) {
-			DEBUG_MAIN(("Adding encrypted HTML body as attachment\n"));
-                       current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach));
-                       memset(current_attach, 0, sizeof(pst_item_attach));
-                       current_attach->next = item->attach;
-                       item->attach = current_attach;
-
-                       current_attach->data = item->email->encrypted_htmlbody;
-                       current_attach->size = item->email->encrypted_htmlbody_size;
+			DEBUG_EMAIL(("Adding encrypted HTML body as attachment\n"));
+			current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach));
+			memset(current_attach, 0, sizeof(pst_item_attach));
+			current_attach->next = item->attach;
+			item->attach = current_attach;
+			current_attach->data = item->email->encrypted_htmlbody;
+			current_attach->size = item->email->encrypted_htmlbody_size;
 			item->email->encrypted_htmlbody = 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");
 	}
+
 	// attachments
+	base64_body = 0;
 	attach_num = 0;
-       for(current_attach = item->attach;
-           current_attach;
-           current_attach = current_attach->next) {
-		DEBUG_MAIN(("write_normal_email: Attempting Attachment encoding\n"));
-               if (current_attach->data == NULL) {
-                       DEBUG_MAIN(("write_normal_email: Data of attachment is NULL!. Size is supposed to be %i\n", current_attach->size));
+	for (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));
 		}
-		attach_num++;
 		if (mode == MODE_SEPERATE && !mode_MH)
-                       write_separate_attachment(f_name, current_attach, attach_num, pst);
+			write_separate_attachment(f_name, current_attach, ++attach_num, pst);
 		else
-                       write_inline_attachment(f_output, current_attach, boundary, pst);
+			write_inline_attachment(f_output, current_attach, boundary, pst);
 	}
 	if (mode != MODE_SEPERATE) { /* do not add a boundary after the last attachment for mode_MH */
-		DEBUG_MAIN(("write_normal_email: Writing buffer between emails\n"));
-		if (boundary)
-			fprintf(f_output, "\n--%s--\n", boundary);
+		DEBUG_EMAIL(("Writing buffer between emails\n"));
+		if (boundary) fprintf(f_output, "\n--%s--\n", boundary);
 		fprintf(f_output, "\n\n");
 	}
-	if (boundary)
-		free (boundary);
+	if (boundary) free (boundary);
+	DEBUG_RET();
 }
 
+
 void write_vcard(FILE* f_output, pst_item_contact* contact, char comment[])
 {
+	DEBUG_ENT("write_vcard");
 	// the specification I am following is (hopefully) RFC2426 vCard Mime Directory Profile
 	fprintf(f_output, "BEGIN:VCARD\n");
 	fprintf(f_output, "FN:%s\n", rfc2426_escape(contact->fullname));
 	fprintf(f_output, "N:%s;%s;%s;%s;%s\n",
-		rfc2426_escape((contact->surname==NULL?"":contact->surname)),
-		rfc2426_escape((contact->first_name==NULL?"":contact->first_name)),
-		rfc2426_escape((contact->middle_name==NULL?"":contact->middle_name)),
-		rfc2426_escape((contact->display_name_prefix==NULL?"":contact->display_name_prefix)),
-		rfc2426_escape((contact->suffix==NULL?"":contact->suffix)));
-	if (contact->nickname != NULL)
+		(!contact->surname) 			? "" : rfc2426_escape(contact->surname),
+		(!contact->first_name)			? "" : rfc2426_escape(contact->first_name),
+		(!contact->middle_name) 		? "" : rfc2426_escape(contact->middle_name),
+		(!contact->display_name_prefix) ? "" : rfc2426_escape(contact->display_name_prefix),
+		(!contact->suffix)				? "" : rfc2426_escape(contact->suffix));
+	if (contact->nickname)
 		fprintf(f_output, "NICKNAME:%s\n", rfc2426_escape(contact->nickname));
-	if (contact->address1 != NULL)
+	if (contact->address1)
 		fprintf(f_output, "EMAIL:%s\n", rfc2426_escape(contact->address1));
-	if (contact->address2 != NULL)
+	if (contact->address2)
 		fprintf(f_output, "EMAIL:%s\n", rfc2426_escape(contact->address2));
-	if (contact->address3 != NULL)
+	if (contact->address3)
 		fprintf(f_output, "EMAIL:%s\n", rfc2426_escape(contact->address3));
-	if (contact->birthday != NULL)
+	if (contact->birthday)
 		fprintf(f_output, "BDAY:%s\n", rfc2425_datetime_format(contact->birthday));
-	if (contact->home_address != NULL) {
+	if (contact->home_address) {
 		fprintf(f_output, "ADR;TYPE=home:%s;%s;%s;%s;%s;%s;%s\n",
-			rfc2426_escape((contact->home_po_box!=NULL?contact->home_po_box:"")),
-			"", // extended Address
-			rfc2426_escape((contact->home_street!=NULL?contact->home_street:"")),
-			rfc2426_escape((contact->home_city!=NULL?contact->home_city:"")),
-			rfc2426_escape((contact->home_state!=NULL?contact->home_state:"")),
-			rfc2426_escape((contact->home_postal_code!=NULL?contact->home_postal_code:"")),
-			rfc2426_escape((contact->home_country!=NULL?contact->home_country:"")));
+			(!contact->home_po_box) 	 ? "" : rfc2426_escape(contact->home_po_box),
+			   "", // extended Address
+			(!contact->home_street) 	 ? "" : rfc2426_escape(contact->home_street),
+			(!contact->home_city)		 ? "" : rfc2426_escape(contact->home_city),
+			(!contact->home_state)		 ? "" : rfc2426_escape(contact->home_state),
+			(!contact->home_postal_code) ? "" : rfc2426_escape(contact->home_postal_code),
+			(!contact->home_country)	 ? "" : rfc2426_escape(contact->home_country));
 		fprintf(f_output, "LABEL;TYPE=home:%s\n", rfc2426_escape(contact->home_address));
 	}
-	if (contact->business_address != NULL) {
+	if (contact->business_address) {
 		fprintf(f_output, "ADR;TYPE=work:%s;%s;%s;%s;%s;%s;%s\n",
-			rfc2426_escape((contact->business_po_box!=NULL?contact->business_po_box:"")),
+			(!contact->business_po_box) 	 ? "" : rfc2426_escape(contact->business_po_box),
 			"", // extended Address
-			rfc2426_escape((contact->business_street!=NULL?contact->business_street:"")),
-			rfc2426_escape((contact->business_city!=NULL?contact->business_city:"")),
-			rfc2426_escape((contact->business_state!=NULL?contact->business_state:"")),
-			rfc2426_escape((contact->business_postal_code!=NULL?contact->business_postal_code:"")),
-			rfc2426_escape((contact->business_country!=NULL?contact->business_country:"")));
+			(!contact->business_street) 	 ? "" : rfc2426_escape(contact->business_street),
+			(!contact->business_city)		 ? "" : rfc2426_escape(contact->business_city),
+			(!contact->business_state)		 ? "" : rfc2426_escape(contact->business_state),
+			(!contact->business_postal_code) ? "" : rfc2426_escape(contact->business_postal_code),
+			(!contact->business_country)	 ? "" : rfc2426_escape(contact->business_country));
 		fprintf(f_output, "LABEL;TYPE=work:%s\n", rfc2426_escape(contact->business_address));
 	}
-	if (contact->other_address != NULL) {
+	if (contact->other_address) {
 		fprintf(f_output, "ADR;TYPE=postal:%s;%s;%s;%s;%s;%s;%s\n",
-			rfc2426_escape((contact->other_po_box != NULL ?
-					contact->business_po_box:"")),
+			(!contact->other_po_box)	   ? "" : rfc2426_escape(contact->business_po_box),
 			"", // extended Address
-			rfc2426_escape((contact->other_street != NULL ?
-					contact->other_street:"")),
-			rfc2426_escape((contact->other_city != NULL ?
-					contact->other_city:"")),
-			rfc2426_escape((contact->other_state != NULL ?
-					contact->other_state:"")),
-			rfc2426_escape((contact->other_postal_code != NULL ?
-					contact->other_postal_code:"")),
-			rfc2426_escape((contact->other_country != NULL ?
-					contact->other_country:"")));
-		fprintf(f_output, "ADR;TYPE=postal:%s\n",
-			rfc2426_escape(contact->other_address));
+			(!contact->other_street)	   ? "" : rfc2426_escape(contact->other_street),
+			(!contact->other_city)		   ? "" : rfc2426_escape(contact->other_city),
+			(!contact->other_state) 	   ? "" : rfc2426_escape(contact->other_state),
+			(!contact->other_postal_code)  ? "" : rfc2426_escape(contact->other_postal_code),
+			(!contact->other_country)	   ? "" : rfc2426_escape(contact->other_country));
+		fprintf(f_output, "LABEL;TYPE=postal:%s\n", rfc2426_escape(contact->other_address));
 	}
-	if (contact->business_fax != NULL)
+	if (contact->business_fax)
 		fprintf(f_output, "TEL;TYPE=work,fax:%s\n",
 			rfc2426_escape(contact->business_fax));
-	if (contact->business_phone != NULL)
+	if (contact->business_phone)
 		fprintf(f_output, "TEL;TYPE=work,voice:%s\n",
 			rfc2426_escape(contact->business_phone));
-	if (contact->business_phone2 != NULL)
+	if (contact->business_phone2)
 		fprintf(f_output, "TEL;TYPE=work,voice:%s\n",
 			rfc2426_escape(contact->business_phone2));
-	if (contact->car_phone != NULL)
+	if (contact->car_phone)
 		fprintf(f_output, "TEL;TYPE=car,voice:%s\n",
 			rfc2426_escape(contact->car_phone));
-	if (contact->home_fax != NULL)
+	if (contact->home_fax)
 		fprintf(f_output, "TEL;TYPE=home,fax:%s\n",
 			rfc2426_escape(contact->home_fax));
-	if (contact->home_phone != NULL)
+	if (contact->home_phone)
 		fprintf(f_output, "TEL;TYPE=home,voice:%s\n",
 			rfc2426_escape(contact->home_phone));
-	if (contact->home_phone2 != NULL)
+	if (contact->home_phone2)
 		fprintf(f_output, "TEL;TYPE=home,voice:%s\n",
 			rfc2426_escape(contact->home_phone2));
-	if (contact->isdn_phone != NULL)
+	if (contact->isdn_phone)
 		fprintf(f_output, "TEL;TYPE=isdn:%s\n",
 			rfc2426_escape(contact->isdn_phone));
-	if (contact->mobile_phone != NULL)
+	if (contact->mobile_phone)
 		fprintf(f_output, "TEL;TYPE=cell,voice:%s\n",
 			rfc2426_escape(contact->mobile_phone));
-	if (contact->other_phone != NULL)
+	if (contact->other_phone)
 		fprintf(f_output, "TEL;TYPE=msg:%s\n",
 			rfc2426_escape(contact->other_phone));
-	if (contact->pager_phone != NULL)
+	if (contact->pager_phone)
 		fprintf(f_output, "TEL;TYPE=pager:%s\n",
 			rfc2426_escape(contact->pager_phone));
-	if (contact->primary_fax != NULL)
+	if (contact->primary_fax)
 		fprintf(f_output, "TEL;TYPE=fax,pref:%s\n",
 			rfc2426_escape(contact->primary_fax));
-	if (contact->primary_phone != NULL)
+	if (contact->primary_phone)
 		fprintf(f_output, "TEL;TYPE=phone,pref:%s\n",
 			rfc2426_escape(contact->primary_phone));
-	if (contact->radio_phone != NULL)
+	if (contact->radio_phone)
 		fprintf(f_output, "TEL;TYPE=pcs:%s\n",
 			rfc2426_escape(contact->radio_phone));
-	if (contact->telex != NULL)
+	if (contact->telex)
 		fprintf(f_output, "TEL;TYPE=bbs:%s\n",
 			rfc2426_escape(contact->telex));
-	if (contact->job_title != NULL)
+	if (contact->job_title)
 		fprintf(f_output, "TITLE:%s\n",
 			rfc2426_escape(contact->job_title));
-	if (contact->profession != NULL)
+	if (contact->profession)
 		fprintf(f_output, "ROLE:%s\n",
 			rfc2426_escape(contact->profession));
-	if (contact->assistant_name != NULL
-	    || contact->assistant_phone != NULL) {
-		fprintf(f_output, "AGENT:BEGIN:VCARD\\n");
-		if (contact->assistant_name != NULL)
-			fprintf(f_output, "FN:%s\\n",
+	if (contact->assistant_name
+		|| contact->assistant_phone) {
+		fprintf(f_output, "AGENT:BEGIN:VCARD\n");
+		if (contact->assistant_name)
+			fprintf(f_output, "FN:%s\n",
 				rfc2426_escape(contact->assistant_name));
-		if (contact->assistant_phone != NULL)
-			fprintf(f_output, "TEL:%s\\n",
+		if (contact->assistant_phone)
+			fprintf(f_output, "TEL:%s\n",
 				rfc2426_escape(contact->assistant_phone));
 	}
-	if (contact->company_name != NULL)
+	if (contact->company_name)
 		fprintf(f_output, "ORG:%s\n",
 			rfc2426_escape(contact->company_name));
-	if (comment != NULL)
+	if (comment)
 		fprintf(f_output, "NOTE:%s\n", rfc2426_escape(comment));
 
 	fprintf(f_output, "VERSION: 3.0\n");
 	fprintf(f_output, "END:VCARD\n\n");
+	DEBUG_RET();
 }
 
+
 void write_appointment(FILE* f_output, pst_item_appointment* appointment,
-		       pst_item_email* email, FILETIME* create_date, FILETIME* modify_date)
+			   pst_item_email* email, FILETIME* create_date, FILETIME* modify_date)
 {
 	fprintf(f_output, "BEGIN:VEVENT\n");
-	if (create_date != NULL)
+	if (create_date)
 		fprintf(f_output, "CREATED:%s\n",
 			rfc2445_datetime_format(create_date));
-	if (modify_date != NULL)
+	if (modify_date)
 		fprintf(f_output, "LAST-MOD:%s\n",
 			rfc2445_datetime_format(modify_date));
-	if (email != NULL && email->subject != NULL)
+	if (email && email->subject)
 		fprintf(f_output, "SUMMARY:%s\n",
 			rfc2426_escape(email->subject->subj));
-	if (email != NULL && email->body != NULL)
+	if (email && email->body)
 		fprintf(f_output, "DESCRIPTION:%s\n",
 			rfc2426_escape(email->body));
-	if (appointment != NULL && appointment->start != NULL)
+	if (appointment && appointment->start)
 		fprintf(f_output, "DTSTART;VALUE=DATE-TIME:%s\n",
 			rfc2445_datetime_format(appointment->start));
-	if (appointment != NULL && appointment->end != NULL)
+	if (appointment && appointment->end)
 		fprintf(f_output, "DTEND;VALUE=DATE-TIME:%s\n",
 			rfc2445_datetime_format(appointment->end));
-	if (appointment != NULL && appointment->location != NULL)
+	if (appointment && appointment->location)
 		fprintf(f_output, "LOCATION:%s\n",
 			rfc2426_escape(appointment->location));
-	if (appointment != NULL) {
+	if (appointment) {
 		switch (appointment->showas) {
 		case PST_FREEBUSY_TENTATIVE:
 			fprintf(f_output, "STATUS:TENTATIVE\n");
@@ -1429,8 +1499,10 @@
 	fprintf(f_output, "END:VEVENT\n\n");
 }
 
+
 void create_enter_dir(struct file_ll* f, char file_as[], int mode, int overwrite)
 {
+	DEBUG_ENT("create_enter_dir");
 	if (mode == MODE_KMAIL)
 		f->name = mk_kmail_dir(file_as); //create directory and form filename
 	else if (mode == MODE_RECURSE)
@@ -1442,7 +1514,7 @@
 		memset(f->name, 0, 10);
 		//		sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->email_count);
 	} else {
-		f->name = (char*) xmalloc(strlen(file_as)+strlen(OUTPUT_TEMPLATE+1));
+		f->name = (char*) xmalloc(strlen(file_as)+strlen(OUTPUT_TEMPLATE)+1);
 		sprintf(f->name, OUTPUT_TEMPLATE, file_as);
 	}
 
@@ -1455,12 +1527,12 @@
 
 		sprintf(temp, "%s", f->name);
 		temp = check_filename(temp);
-		while ((f->output = fopen(temp, "r")) != NULL) {
-			DEBUG_MAIN(("create_enter_dir: need to increase filename cause one already exists with that name\n"));
-			DEBUG_MAIN(("create_enter_dir: - increasing it to %s%d\n", f->name, x));
+		while ((f->output = fopen(temp, "r"))) {
+			DEBUG_MAIN(("need to increase filename because one already exists with that name\n"));
+			DEBUG_MAIN(("- increasing it to %s%d\n", f->name, x));
 			x++;
 			sprintf(temp, "%s%08d", f->name, x);
-			DEBUG_MAIN(("create_enter_dir: - trying \"%s\"\n", f->name));
+			DEBUG_MAIN(("- trying \"%s\"\n", f->name));
 			if (x == 99999999) {
 				DIE(("create_enter_dir: Why can I not create a folder %s? I have tried %i extensions...\n", f->name, x));
 			}
@@ -1474,12 +1546,13 @@
 		}
 	}
 
-	DEBUG_MAIN(("create_enter_dir: f->name = %s\nitem->folder_name = %s\n", f->name, file_as));
+	DEBUG_MAIN(("f->name = %s\nitem->folder_name = %s\n", f->name, file_as));
 	if (mode != MODE_SEPERATE) {
 		f->name = check_filename(f->name);
-		if ((f->output = fopen(f->name, "w")) == NULL) {
+		if (!(f->output = fopen(f->name, "w"))) {
 			DIE(("create_enter_dir: Could not open file \"%s\" for write\n", f->name));
 		}
 	}
+	DEBUG_RET();
 }
 
--- a/xml/libpst.in	Sat Feb 25 16:16:15 2006 -0800
+++ b/xml/libpst.in	Tue Jul 10 17:17:28 2007 -0700
@@ -2,17 +2,24 @@
     <title>@PACKAGE@ Utilities - Version @VERSION@</title>
     <partintro>
         <title>Packages</title>
-        <para>The various source and binary packages are available at <ulink
-        url="http://www.five-ten-sg.com/@PACKAGE@/packages/">http://www.five-ten-sg.com/@PACKAGE@/packages/</ulink>
-        The most recent documentation is available at <ulink
-        url="http://www.five-ten-sg.com/@PACKAGE@/">http://www.five-ten-sg.com/@PACKAGE@/</ulink>
-        </para>
+
+            <para>This is a fork of the libpst project at SourceForge.  Another fork
+            is located at <ulink
+            url="http://alioth.debian.org/projects/libpst/">http://alioth.debian.org/projects/libpst/</ulink>
+            </para>
+
+            <para>The various source and binary packages are available at <ulink
+            url="http://www.five-ten-sg.com/@PACKAGE@/packages/">http://www.five-ten-sg.com/@PACKAGE@/packages/</ulink>
+            The most recent documentation is available at <ulink
+            url="http://www.five-ten-sg.com/@PACKAGE@/">http://www.five-ten-sg.com/@PACKAGE@/</ulink>
+            </para>
+
     </partintro>
 
 
     <refentry id="readpst.1">
         <refentryinfo>
-            <date>2006-02-20</date>
+            <date>2007-07-10</date>
         </refentryinfo>
 
         <refmeta>
@@ -30,6 +37,7 @@
             <title>Synopsis</title>
             <cmdsynopsis>
                 <command>readpst</command>
+                <arg><option>-b</option></arg>
                 <arg><option>-c <replaceable class="parameter">format</replaceable></option></arg>
                 <arg><option>-d <replaceable class="parameter">debug-file</replaceable></option></arg>
                 <arg><option>-h</option></arg>
@@ -57,6 +65,12 @@
             <title>Options</title>
             <variablelist>
                 <varlistentry>
+                    <term>-b</term>
+                    <listitem><para>
+                        Do not save the attachments for the RTF format of the email body.
+                    </para></listitem>
+                </varlistentry>
+                <varlistentry>
                     <term>-c <replaceable class="parameter">format</replaceable></term>
                     <listitem><para>
                         Set the Contact output mode. Use -cv for vcard format or -cl for an email list.
@@ -73,7 +87,7 @@
                 <varlistentry>
                     <term>-h</term>
                     <listitem><para>
-                        Show summary of options. Subsequent options are then ignored.
+                        Show summary of options and exit.
                     </para></listitem>
                 </varlistentry>
                 <varlistentry>
@@ -129,7 +143,7 @@
                 <varlistentry>
                     <term>-V</term>
                     <listitem><para>
-                        Show program version. Subsequent options are then ignored.
+                        Show program version and exit.
                     </para></listitem>
                 </varlistentry>
                 <varlistentry>
@@ -191,7 +205,7 @@
 
     <refentry id="readpstlog.1">
         <refentryinfo>
-            <date>2006-02-20</date>
+            <date>2007-07-10</date>
         </refentryinfo>
 
         <refmeta>
@@ -359,7 +373,7 @@
 
     <refentry id="pst2ldif.1">
         <refentryinfo>
-            <date>2006-02-20</date>
+            <date>2007-07-10</date>
         </refentryinfo>
 
         <refmeta>
@@ -474,7 +488,7 @@
 
     <refentry id="pst.5">
         <refentryinfo>
-            <date>2006-02-20</date>
+            <date>2007-07-10</date>
         </refentryinfo>
 
         <refmeta>