# HG changeset patch # User Carl Byington # Date 1236548126 25200 # Node ID cda7c812ec01417c44406f450269c7583856c83d # Parent 06aa84023b48e6298d09d1d5c1336b53ff7cea61 track character set individually for each mapi element diff -r 06aa84023b48 -r cda7c812ec01 ChangeLog --- a/ChangeLog Thu Mar 05 08:23:32 2009 -0800 +++ b/ChangeLog Sun Mar 08 14:35:26 2009 -0700 @@ -4,6 +4,9 @@ * remove decrypt option from getidblock - we always decrypt. * rename some structure fields to reflect our better understanding of the pst format. + * track character set for each mapi element, since some could be + unicode (therefore utf8) and others sbcs with character set + specified by the mapi object. LibPST 0.6.29 (2009-02-24) =============================== diff -r 06aa84023b48 -r cda7c812ec01 regression/regression-tests.bash --- a/regression/regression-tests.bash Thu Mar 05 08:23:32 2009 -0800 +++ b/regression/regression-tests.bash Sun Mar 08 14:35:26 2009 -0700 @@ -77,8 +77,8 @@ #doldif 13 test-text.pst #doldif 14 joe.romanowski.pst #doldif 15 hourig1.pst - #doldif 16 hourig2.pst - #doldif 17 hourig3.pst + ##doldif 16 hourig2.pst + ##doldif 17 hourig3.pst #doldif 18 test-mac.pst doldif 19 harris.pst else @@ -100,7 +100,7 @@ #dopst 16 hourig2.pst #dopst 17 hourig3.pst dopst 18 test-mac.pst - dopst 19 harris.pst + #dopst 19 harris.pst fi grep 'lost:' *err | grep -v 'lost: 0 ' diff -r 06aa84023b48 -r cda7c812ec01 src/libpst.c --- a/src/libpst.c Thu Mar 05 08:23:32 2009 -0800 +++ b/src/libpst.c Sun Mar 08 14:35:26 2009 -0700 @@ -1115,7 +1115,7 @@ if ((id2_ptr = pst_getID2(id2_head, (uint64_t)0x692))) { // DSN/MDN reports? - DEBUG_EMAIL(("DSN/MDN processing \n")); + DEBUG_EMAIL(("DSN/MDN processing\n")); list = pst_parse_block(pf, id2_ptr->id->id, id2_head, NULL); if (!list) { DEBUG_WARN(("ERROR error processing main DSN/MDN record\n")); @@ -1141,14 +1141,6 @@ } if ((id2_ptr = pst_getID2(id2_head, (uint64_t)0x671))) { - // should not have any existing attachments anyway - //while (item->attach) { - // DEBUG_EMAIL(("throw away existing attachment\n")); - // attach = item->attach->next; - // free(item->attach); - // item->attach = attach; - //} - DEBUG_EMAIL(("ATTACHMENT processing attachment\n")); list = pst_parse_block(pf, id2_ptr->id->id, id2_head, NULL); if (!list) { @@ -1718,7 +1710,7 @@ // This version of free does NULL check first #define SAFE_FREE(x) {if (x) free(x);} - +#define SAFE_FREE_STR(x) SAFE_FREE(x.str) // check if item->email is NULL, and init if so #define MALLOC_EMAIL(x) { if (!x->email) { x->email = (pst_item_email*) xmalloc(sizeof(pst_item_email)); memset(x->email, 0, sizeof(pst_item_email) );} } @@ -1727,19 +1719,70 @@ #define MALLOC_MESSAGESTORE(x) { if (!x->message_store) { x->message_store = (pst_item_message_store*) xmalloc(sizeof(pst_item_message_store)); memset(x->message_store, 0, sizeof(pst_item_message_store));} } #define MALLOC_JOURNAL(x) { if (!x->journal) { x->journal = (pst_item_journal*) xmalloc(sizeof(pst_item_journal)); memset(x->journal, 0, sizeof(pst_item_journal) );} } #define MALLOC_APPOINTMENT(x) { if (!x->appointment) { x->appointment = (pst_item_appointment*) xmalloc(sizeof(pst_item_appointment)); memset(x->appointment, 0, sizeof(pst_item_appointment) );} } + // malloc space and copy the current item's data null terminated -#define LIST_COPY(targ, type) { \ - targ = type realloc(targ, list->items[x]->size+1); \ - memcpy(targ, list->items[x]->data, list->items[x]->size); \ - memset(((char*)targ)+list->items[x]->size, 0, (size_t)1); \ +#define LIST_COPY(targ, type) { \ + targ = type realloc(targ, list->items[x]->size+1); \ + memcpy(targ, list->items[x]->data, list->items[x]->size); \ + memset(((char*)targ)+list->items[x]->size, 0, (size_t)1); \ +} + +#define LIST_COPY_BOOL(label, targ) { \ + if (*(int16_t*)list->items[x]->data) { \ + DEBUG_EMAIL((label" - True\n")); \ + targ = 1; \ + } else { \ + DEBUG_EMAIL((label" - False\n")); \ + targ = 0; \ + } \ +} + +#define LIST_COPY_EMAIL_BOOL(label, targ) { \ + MALLOC_EMAIL(item); \ + LIST_COPY_BOOL(label, targ) \ +} + +#define LIST_COPY_CONTACT_BOOL(label, targ) { \ + MALLOC_CONTACT(item); \ + LIST_COPY_BOOL(label, targ) \ } + +#define LIST_COPY_APPT_BOOL(label, targ) { \ + MALLOC_APPOINTMENT(item); \ + LIST_COPY_BOOL(label, targ) \ +} + +// malloc space and copy the current item's data null terminated +// including the utf8 flag +#define LIST_COPY_STR(label, targ) { \ + LIST_COPY(targ.str, (char*)); \ + targ.is_utf8 = (list->items[x]->type == 0x1f) ? 1 : 0; \ + DEBUG_EMAIL((label" - unicode %d - %s\n", targ.is_utf8, targ.str)); \ +} + +#define LIST_COPY_EMAIL_STR(label, targ) { \ + MALLOC_EMAIL(item); \ + LIST_COPY_STR(label, targ); \ +} + +#define LIST_COPY_CONTACT_STR(label, targ) { \ + MALLOC_CONTACT(item); \ + LIST_COPY_STR(label, targ); \ +} + +#define LIST_COPY_APPT_STR(label, targ) { \ + MALLOC_APPOINTMENT(item); \ + LIST_COPY_STR(label, targ); \ +} + // malloc space and copy the item filetime -#define LIST_COPY_TIME(targ) { \ - targ = (FILETIME*) realloc(targ, sizeof(FILETIME)); \ - memcpy(targ, list->items[x]->data, list->items[x]->size); \ - LE32_CPU(targ->dwLowDateTime); \ - LE32_CPU(targ->dwHighDateTime); \ +#define LIST_COPY_TIME(targ) { \ + targ = (FILETIME*) realloc(targ, sizeof(FILETIME)); \ + memcpy(targ, list->items[x]->data, list->items[x]->size); \ + LE32_CPU(targ->dwLowDateTime); \ + LE32_CPU(targ->dwHighDateTime); \ } + // malloc space and copy the current item's data and size #define LIST_COPY_SIZE(targ, type, mysize) { \ mysize = list->items[x]->size; \ @@ -1779,8 +1822,8 @@ } while (list) { - int32_t x = 0; - while (x < list->count_item) { + int32_t x; + for (x=0; xcount_item; x++) { int32_t t; pst_item_extra_field *ef; // check here to see if the id is one that is mapped. @@ -1788,7 +1831,6 @@ switch (list->items[x]->id) { case PST_ATTRIB_HEADER: // CUSTOM attribute for saying the Extra Headers - DEBUG_EMAIL(("Extra Field - ")); if (list->items[x]->extra) { ef = (pst_item_extra_field*) xmalloc(sizeof(pst_item_extra_field)); memset(ef, 0, sizeof(pst_item_extra_field)); @@ -1797,7 +1839,7 @@ LIST_COPY(ef->value, (char*)); ef->next = item->extra_fields; item->extra_fields = ef; - DEBUG_EMAIL(("\"%s\" = \"%s\"\n", ef->field_name, ef->value)); + DEBUG_EMAIL(("Extra Field - \"%s\" = \"%s\"\n", ef->field_name, ef->value)); if (strcmp(ef->field_name, "content-type") == 0) { char *p = strstr(ef->value, "charset=\""); if (p) { @@ -1807,8 +1849,9 @@ *pp = '\0'; char *set = strdup(p); *pp = '"'; - if (item->body_charset) free(item->body_charset); - item->body_charset = set; + if (item->body_charset.str) free(item->body_charset.str); + item->body_charset.str = set; + item->body_charset.is_utf8 = 1; DEBUG_EMAIL(("body charset %s from content-type extra field\n", set)); } } @@ -1820,15 +1863,8 @@ break; case 0x0002: // PR_ALTERNATE_RECIPIENT_ALLOWED // If set to true, the sender allows this email to be autoforwarded - DEBUG_EMAIL(("AutoForward allowed - ")); - MALLOC_EMAIL(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->email->autoforward = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->email->autoforward = -1; - } + LIST_COPY_EMAIL_BOOL("AutoForward allowed", item->email->autoforward); + if (!item->email->autoforward) item->email->autoforward = -1; break; case 0x0003: // Extended Attributes table DEBUG_EMAIL(("Extended Attributes Table - NOT PROCESSED\n")); @@ -1838,18 +1874,16 @@ // 0 - Low // 1 - Normal // 2 - High - DEBUG_EMAIL(("Importance Level - ")); MALLOC_EMAIL(item); memcpy(&(item->email->importance), list->items[x]->data, sizeof(item->email->importance)); LE32_CPU(item->email->importance); t = item->email->importance; - DEBUG_EMAIL(("%s [%i]\n", ((int)t==0?"Low": - ((int)t==1?"Normal": - "High")), t)); + DEBUG_EMAIL(("Importance Level - %s [%i]\n", ((int)t==0?"Low" : + ((int)t==1?"Normal" : + "High")), t)); break; case 0x001A: // PR_MESSAGE_CLASS Ascii type of messages - NOT FOLDERS // must be case insensitive - DEBUG_EMAIL(("IPM.x - ")); LIST_COPY(item->ascii_type, (char*)); if (pst_strincmp("IPM.Note", item->ascii_type, 8) == 0) // the string begins with IPM.Note... @@ -1872,52 +1906,28 @@ else item->type = PST_TYPE_OTHER; - DEBUG_EMAIL(("%s\n", item->ascii_type)); + DEBUG_EMAIL(("IPM.x - %s\n", item->ascii_type)); break; case 0x0023: // PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED // set if the sender wants a delivery report from all recipients - DEBUG_EMAIL(("Global Delivery Report - ")); - MALLOC_EMAIL(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->email->delivery_report = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->email->delivery_report = 0; - } + LIST_COPY_EMAIL_BOOL("Global Delivery Report", item->email->delivery_report); break; case 0x0026: // PR_PRIORITY // Priority of a message // -1 NonUrgent // 0 Normal // 1 Urgent - DEBUG_EMAIL(("Priority - ")); MALLOC_EMAIL(item); memcpy(&(item->email->priority), list->items[x]->data, sizeof(item->email->priority)); LE32_CPU(item->email->priority); t = item->email->priority; - DEBUG_EMAIL(("%s [%i]\n", (t<0?"NonUrgent":(t==0?"Normal":"Urgent")), t)); + DEBUG_EMAIL(("Priority - %s [%i]\n", (t<0?"NonUrgent":(t==0?"Normal":"Urgent")), t)); break; case 0x0029: // PR_READ_RECEIPT_REQUESTED - DEBUG_EMAIL(("Read Receipt - ")); - MALLOC_EMAIL(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->email->read_receipt = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->email->read_receipt = 0; - } + LIST_COPY_EMAIL_BOOL("Read Receipt", item->email->read_receipt); break; case 0x002B: // PR_RECIPIENT_REASSIGNMENT_PROHIBITED - DEBUG_EMAIL(("Reassignment Prohibited (Private) - ")); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->private_member = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->private_member = 0; - } + LIST_COPY_BOOL("Reassignment Prohibited (Private)", item->private_member); break; case 0x002E: // PR_ORIGINAL_SENSITIVITY // the sensitivity of the message before being replied to or forwarded @@ -1925,21 +1935,19 @@ // 1 - Personal // 2 - Private // 3 - Company Confidential - DEBUG_EMAIL(("Original Sensitivity - ")); MALLOC_EMAIL(item); memcpy(&(item->email->orig_sensitivity), list->items[x]->data, sizeof(item->email->orig_sensitivity)); LE32_CPU(item->email->orig_sensitivity); t = item->email->orig_sensitivity; - DEBUG_EMAIL(("%s [%i]\n", ((int)t==0?"None": - ((int)t==1?"Personal": - ((int)t==2?"Private": - "Company Confidential"))), t)); + DEBUG_EMAIL(("Original Sensitivity - %s [%i]\n", ((int)t==0?"None" : + ((int)t==1?"Personal" : + ((int)t==2?"Private" : + "Company Confidential"))), t)); break; case 0x0032: // PR_REPORT_TIME - DEBUG_EMAIL(("Report time - ")); MALLOC_EMAIL(item); LIST_COPY_TIME(item->email->report_time); - DEBUG_EMAIL(("%s", fileTimeToAscii(item->email->report_time))); + DEBUG_EMAIL(("Report time - %s\n", fileTimeToAscii(item->email->report_time))); break; case 0x0036: // PR_SENSITIVITY // sender's opinion of the sensitivity of an email @@ -1947,59 +1955,35 @@ // 1 - Personal // 2 - Private // 3 - Company Confidential - DEBUG_EMAIL(("Sensitivity - ")); MALLOC_EMAIL(item); memcpy(&(item->email->sensitivity), list->items[x]->data, sizeof(item->email->sensitivity)); LE32_CPU(item->email->sensitivity); t = item->email->sensitivity; - DEBUG_EMAIL(("%s [%i]\n", ((int)t==0?"None": - ((int)t==1?"Personal": - ((int)t==2?"Private": - "Company Confidential"))), t)); + DEBUG_EMAIL(("Sensitivity - %s [%i]\n", ((int)t==0?"None" : + ((int)t==1?"Personal" : + ((int)t==2?"Private" : + "Company Confidential"))), t)); break; case 0x0037: // PR_SUBJECT raw subject - DEBUG_EMAIL(("Raw Subject - ")); - MALLOC_EMAIL(item); - item->email->subject = (pst_item_email_subject*) realloc(item->email->subject, sizeof(pst_item_email_subject)); - memset(item->email->subject, 0, sizeof(pst_item_email_subject)); - DEBUG_EMAIL((" [size = %i] ", list->items[x]->size)); - if (list->items[x]->size > 0) { - if (isprint(list->items[x]->data[0]) || (list->items[x]->size < 2)) { - // then there are no control bytes at the front - item->email->subject->off1 = 0; - item->email->subject->off2 = 0; - item->email->subject->subj = realloc(item->email->subject->subj, list->items[x]->size+1); - memset(item->email->subject->subj, 0, list->items[x]->size+1); - memcpy(item->email->subject->subj, list->items[x]->data, list->items[x]->size); - } else { - DEBUG_EMAIL(("Raw Subject has control codes\n")); - // there might be some control bytes in the first and second bytes - item->email->subject->off1 = (int)(unsigned)list->items[x]->data[0]; - item->email->subject->off2 = (int)(unsigned)list->items[x]->data[1]; - item->email->subject->subj = realloc(item->email->subject->subj, list->items[x]->size-1); - memset(item->email->subject->subj, 0, list->items[x]->size-1); - memcpy(item->email->subject->subj, &(list->items[x]->data[2]), list->items[x]->size-2); + { + int off = 0; + if ((list->items[x]->size > 2) && (((uint8_t)list->items[x]->data[0]) < 0x20)) { + off = 2; } - DEBUG_EMAIL(("%s\n", item->email->subject->subj)); - } else { - // obviously outlook has decided not to be straight with this one. - item->email->subject->off1 = 0; - item->email->subject->off2 = 0; - item->email->subject = NULL; - DEBUG_EMAIL(("NULL subject detected\n")); + list->items[x]->data += off; + list->items[x]->size -= off; + LIST_COPY_STR("Raw Subject", item->subject); + list->items[x]->size += off; + list->items[x]->data -= off; } break; case 0x0039: // PR_CLIENT_SUBMIT_TIME Date Email Sent/Created - DEBUG_EMAIL(("Date sent - ")); MALLOC_EMAIL(item); LIST_COPY_TIME(item->email->sent_date); - DEBUG_EMAIL(("%s", fileTimeToAscii(item->email->sent_date))); + DEBUG_EMAIL(("Date sent - %s\n", fileTimeToAscii(item->email->sent_date))); break; case 0x003B: // PR_SENT_REPRESENTING_SEARCH_KEY Sender address 1 - DEBUG_EMAIL(("Sent on behalf of address 1 - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->outlook_sender, (char*)); - DEBUG_EMAIL(("%s\n", item->email->outlook_sender)); + LIST_COPY_EMAIL_STR("Sent on behalf of address 1", item->email->outlook_sender); break; case 0x003F: // PR_RECEIVED_BY_ENTRYID Structure containing Recipient DEBUG_EMAIL(("Recipient Structure 1 -- NOT HANDLED\n")); @@ -2010,105 +1994,50 @@ case 0x0041: // PR_SENT_REPRESENTING_ENTRYID Structure containing Sender DEBUG_EMAIL(("Sent on behalf of Structure 1 -- NOT HANDLED\n")); break; - case 0x0042: // PR_SENT_REPRESENTING_NAME Name of Sender Structure - DEBUG_EMAIL(("Sent on behalf of Structure Name - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->outlook_sender_name, (char*)); - DEBUG_EMAIL(("%s\n", item->email->outlook_sender_name)); + case 0x0042: // PR_SENT_REPRESENTING_NAME + LIST_COPY_EMAIL_STR("Sent on behalf of", item->email->outlook_sender_name); break; case 0x0043: // PR_RCVD_REPRESENTING_ENTRYID Recipient Structure 2 DEBUG_EMAIL(("Received on behalf of Structure -- NOT HANDLED\n")); break; - case 0x0044: // PR_RCVD_REPRESENTING_NAME Name of Recipient Structure 2 - DEBUG_EMAIL(("Received on behalf of Structure Name -- NOT HANDLED\n")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->outlook_recipient_name, (char*)); - DEBUG_EMAIL(("%s\n", item->email->outlook_recipient_name)); + case 0x0044: // PR_RCVD_REPRESENTING_NAME + LIST_COPY_EMAIL_STR("Received on behalf of", item->email->outlook_recipient_name); break; case 0x004F: // PR_REPLY_RECIPIENT_ENTRIES Reply-To Structure DEBUG_EMAIL(("Reply-To Structure -- NOT HANDLED\n")); break; case 0x0050: // PR_REPLY_RECIPIENT_NAMES Name of Reply-To Structure - DEBUG_EMAIL(("Name of Reply-To Structure -")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->reply_to, (char*)); - DEBUG_EMAIL(("%s\n", item->email->reply_to)); + LIST_COPY_EMAIL_STR("Reply-To", item->email->reply_to); break; case 0x0051: // PR_RECEIVED_BY_SEARCH_KEY Recipient Address 1 - DEBUG_EMAIL(("Recipient's Address 1 (Search Key) - ")); - MALLOC_EMAIL(item); - LIST_COPY (item->email->outlook_recipient, (char*)); - DEBUG_EMAIL(("%s\n", item->email->outlook_recipient)); + LIST_COPY_EMAIL_STR("Recipient's Address 1", item->email->outlook_recipient); break; case 0x0052: // PR_RCVD_REPRESENTING_SEARCH_KEY Recipient Address 2 - DEBUG_EMAIL(("Received on behalf of Address (Search Key) - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->outlook_recipient2, (char*)); - DEBUG_EMAIL(("%s\n", item->email->outlook_recipient2)); + LIST_COPY_EMAIL_STR("Recipient's Address 2", item->email->outlook_recipient2); break; case 0x0057: // PR_MESSAGE_TO_ME // this user is listed explicitly in the TO address - DEBUG_EMAIL(("My address in TO field - ")); - MALLOC_EMAIL(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->email->message_to_me = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->email->message_to_me = 0; - } + LIST_COPY_EMAIL_BOOL("My address in TO field", item->email->message_to_me); break; case 0x0058: // PR_MESSAGE_CC_ME // this user is listed explicitly in the CC address - DEBUG_EMAIL(("My address in CC field - ")); - MALLOC_EMAIL(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->email->message_cc_me = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->email->message_cc_me = 0; - } + LIST_COPY_EMAIL_BOOL("My address in CC field", item->email->message_cc_me); break; case 0x0059: // PR_MESSAGE_RECIP_ME // this user appears in TO, CC or BCC address list - DEBUG_EMAIL(("Message addressed to me - ")); - MALLOC_EMAIL(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->email->message_recip_me = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->email->message_recip_me = 0; - } + LIST_COPY_EMAIL_BOOL("Message addressed to me", item->email->message_recip_me); break; case 0x0063: // PR_RESPONSE_REQUESTED - DEBUG_EMAIL(("Response requested - ")); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->response_requested = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->response_requested = 0; - } + LIST_COPY_BOOL("Response requested", item->response_requested); break; case 0x0064: // PR_SENT_REPRESENTING_ADDRTYPE Access method for Sender Address - DEBUG_EMAIL(("Sent on behalf of address type - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->sender_access, (char*)); - DEBUG_EMAIL(("%s\n", item->email->sender_access)); + LIST_COPY_EMAIL_STR("Sent on behalf of address type", item->email->sender_access); break; case 0x0065: // PR_SENT_REPRESENTING_EMAIL_ADDRESS Sender Address - DEBUG_EMAIL(("Sent on behalf of Address - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->sender_address, (char*)); - DEBUG_EMAIL(("%s\n", item->email->sender_address)); + LIST_COPY_EMAIL_STR("Sent on behalf of address", item->email->sender_address); break; case 0x0070: // PR_CONVERSATION_TOPIC Processed Subject - DEBUG_EMAIL(("Processed Subject (Conversation Topic) - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->proc_subject, (char*)); - DEBUG_EMAIL(("%s\n", item->email->proc_subject)); + LIST_COPY_EMAIL_STR("Processed Subject (Conversation Topic)", item->email->processed_subject); break; case 0x0071: // PR_CONVERSATION_INDEX DEBUG_EMAIL(("Conversation Index - ")); @@ -2117,52 +2046,28 @@ DEBUG_EMAIL(("%i\n", item->email->conv_index)); break; case 0x0072: // PR_ORIGINAL_DISPLAY_BCC - DEBUG_EMAIL(("Original display bcc - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->original_bcc, (char*)); - DEBUG_EMAIL(("%s\n", item->email->original_bcc)); + LIST_COPY_EMAIL_STR("Original display bcc", item->email->original_bcc); break; case 0x0073: // PR_ORIGINAL_DISPLAY_CC - DEBUG_EMAIL(("Original display cc - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->original_cc, (char*)); - DEBUG_EMAIL(("%s\n", item->email->original_cc)); + LIST_COPY_EMAIL_STR("Original display cc", item->email->original_cc); break; case 0x0074: // PR_ORIGINAL_DISPLAY_TO - DEBUG_EMAIL(("Original display to - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->original_to, (char*)); - DEBUG_EMAIL(("%s\n", item->email->original_to)); + LIST_COPY_EMAIL_STR("Original display to", item->email->original_to); break; case 0x0075: // PR_RECEIVED_BY_ADDRTYPE Recipient Access Method - DEBUG_EMAIL(("Received by Address type - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->recip_access, (char*)); - DEBUG_EMAIL(("%s\n", item->email->recip_access)); + LIST_COPY_EMAIL_STR("Received by Address type", item->email->recip_access); break; case 0x0076: // PR_RECEIVED_BY_EMAIL_ADDRESS Recipient Address - DEBUG_EMAIL(("Received by Address - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->recip_address, (char*)); - DEBUG_EMAIL(("%s\n", item->email->recip_address)); + LIST_COPY_EMAIL_STR("Received by Address", item->email->recip_address); break; case 0x0077: // PR_RCVD_REPRESENTING_ADDRTYPE Recipient Access Method 2 - DEBUG_EMAIL(("Received on behalf of Address type - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->recip2_access, (char*)); - DEBUG_EMAIL(("%s\n", item->email->recip2_access)); + LIST_COPY_EMAIL_STR("Received on behalf of Address type", item->email->recip2_access); break; case 0x0078: // PR_RCVD_REPRESENTING_EMAIL_ADDRESS Recipient Address 2 - DEBUG_EMAIL(("Received on behalf of Address -")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->recip2_address, (char*)); - DEBUG_EMAIL(("%s\n", item->email->recip2_address)); + LIST_COPY_EMAIL_STR("Received on behalf of Address", item->email->recip2_address); break; case 0x007D: // PR_TRANSPORT_MESSAGE_HEADERS Internet Header - DEBUG_EMAIL(("Internet Header - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->header, (char*)); - DEBUG_EMAIL(("%s\n", item->email->header)); + LIST_COPY_EMAIL_STR("Internet Header", item->email->header); break; case 0x0C04: // PR_NDR_REASON_CODE MALLOC_EMAIL(item); @@ -2180,22 +2085,9 @@ break; case 0x0C06: // PR_NON_RECEIPT_NOTIFICATION_REQUESTED DEBUG_EMAIL(("Non-Receipt Notification Requested - (ignored) - ")); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - } else { - DEBUG_EMAIL(("False\n")); - } break; case 0x0C17: // PR_REPLY_REQUESTED - DEBUG_EMAIL(("Reply Requested - ")); - MALLOC_EMAIL(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->email->reply_requested = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->email->reply_requested = 0; - } + LIST_COPY_EMAIL_BOOL("Reply Requested", item->email->reply_requested); break; case 0x0C19: // PR_SENDER_ENTRYID Sender Structure 2 DEBUG_EMAIL(("Sender Structure 2 -- NOT HANDLED\n")); @@ -2204,28 +2096,16 @@ DEBUG_EMAIL(("Name of Sender Structure 2 -- NOT HANDLED\n")); break; case 0x0C1B: // PR_SUPPLEMENTARY_INFO - DEBUG_EMAIL(("Supplementary info - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->supplementary_info, (char*)); - DEBUG_EMAIL(("%s\n", item->email->supplementary_info)); + LIST_COPY_EMAIL_STR("Supplementary info", item->email->supplementary_info); break; case 0x0C1D: // PR_SENDER_SEARCH_KEY Name of Sender Address 2 - DEBUG_EMAIL(("Name of Sender Address 2 (Sender search key) - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->outlook_sender2, (char*)); - DEBUG_EMAIL(("%s\n", item->email->outlook_sender2)); + LIST_COPY_EMAIL_STR("Name of Sender Address 2 (Sender search key)", item->email->outlook_sender2); break; case 0x0C1E: // PR_SENDER_ADDRTYPE Sender Address 2 access method - DEBUG_EMAIL(("Sender Address type - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->sender2_access, (char*)); - DEBUG_EMAIL(("%s\n", item->email->sender2_access)); + LIST_COPY_EMAIL_STR("Sender Address type", item->email->sender2_access); break; case 0x0C1F: // PR_SENDER_EMAIL_ADDRESS Sender Address 2 - DEBUG_EMAIL(("Sender Address - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->sender2_address, (char*)); - DEBUG_EMAIL(("%s\n", item->email->sender2_address)); + LIST_COPY_EMAIL_STR("Sender Address", item->email->sender2_address); break; case 0x0C20: // PR_NDR_STATUS_CODE MALLOC_EMAIL(item); @@ -2235,34 +2115,16 @@ DEBUG_EMAIL(("NDR status code - [%i]\n", (int)t)); break; case 0x0E01: // PR_DELETE_AFTER_SUBMIT - // I am not too sure how this works - DEBUG_EMAIL(("Delete after submit - ")); - MALLOC_EMAIL(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->email->delete_after_submit = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->email->delete_after_submit = 0; - } + LIST_COPY_EMAIL_BOOL("Delete after submit", item->email->delete_after_submit); break; case 0x0E02: // PR_DISPLAY_BCC BCC Addresses - DEBUG_EMAIL(("Display BCC Addresses - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->bcc_address, (char*)); - DEBUG_EMAIL(("%s\n", item->email->bcc_address)); + LIST_COPY_EMAIL_STR("Display BCC Addresses", item->email->bcc_address); break; case 0x0E03: // PR_DISPLAY_CC CC Addresses - DEBUG_EMAIL(("Display CC Addresses - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->cc_address, (char*)); - DEBUG_EMAIL(("%s\n", item->email->cc_address)); + LIST_COPY_EMAIL_STR("Display CC Addresses", item->email->cc_address); break; case 0x0E04: // PR_DISPLAY_TO Address Sent-To - DEBUG_EMAIL(("Display Sent-To Address - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->sentto_address, (char*)); - DEBUG_EMAIL(("%s\n", item->email->sentto_address)); + LIST_COPY_EMAIL_STR("Display Sent-To Address", item->email->sentto_address); break; case 0x0E06: // PR_MESSAGE_DELIVERY_TIME Date 3 - Email Arrival Date DEBUG_EMAIL(("Date 3 (Delivery Time) - ")); @@ -2306,15 +2168,7 @@ // False means rtf version is more up-to-date than text body // if this value doesn't exist, text body is more up-to-date than rtf and // cannot update to the rtf - DEBUG_EMAIL(("Compressed RTF in Sync - ")); - MALLOC_EMAIL(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->email->rtf_in_sync = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->email->rtf_in_sync = 0; - } + LIST_COPY_EMAIL_BOOL("Compressed RTF in Sync", item->email->rtf_in_sync); break; case 0x0E20: // PR_ATTACH_SIZE binary Attachment data in record DEBUG_EMAIL(("Attachment Size - ")); @@ -2332,19 +2186,10 @@ DEBUG_EMAIL(("\n")); break; case 0x1000: // PR_BODY - MALLOC_EMAIL(item); - LIST_COPY(item->email->body, (char*)); - item->email->body_was_unicode = (list->items[x]->type == 0x1f) ? 1 : 0; - DEBUG_EMAIL(("Plain Text body %s - \n%s\n", (item->email->body_was_unicode) ? "unicode" : "sbcs", - item->email->body)); + LIST_COPY_EMAIL_STR("Plain Text body", item->body); break; case 0x1001: // PR_REPORT_TEXT - DEBUG_EMAIL(("Report Text - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->report_text, (char*)); - item->email->report_was_unicode = (list->items[x]->type == 0x1f) ? 1 : 0; - DEBUG_EMAIL(("Report Text %s - \n%s\n", (item->email->report_was_unicode) ? "unicode" : "sbcs", - item->email->report_text)); + LIST_COPY_EMAIL_STR("Report Text", item->email->report_text); break; case 0x1006: // PR_RTF_SYNC_BODY_CRC DEBUG_EMAIL(("RTF Sync Body CRC - ")); @@ -2365,10 +2210,7 @@ case 0x1008: // PR_RTF_SYNC_BODY_TAG // the first couple of lines of RTF body so that after modification, then beginning can // once again be found - DEBUG_EMAIL(("RTF Sync body tag - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->rtf_body_tag, (char*)); - DEBUG_EMAIL(("%s\n", item->email->rtf_body_tag)); + LIST_COPY_EMAIL_STR("RTF Sync body tag", item->email->rtf_body_tag); break; case 0x1009: // PR_RTF_COMPRESSED // rtf data is lzw compressed @@ -2392,52 +2234,28 @@ DEBUG_EMAIL(("%i\n", item->email->rtf_ws_trailing_count)); break; case 0x1013: // HTML body - MALLOC_EMAIL(item); - LIST_COPY(item->email->htmlbody, (char*)); - item->email->htmlbody_was_unicode = (list->items[x]->type == 0x1f) ? 1 : 0; - DEBUG_EMAIL(("HTML body %s - \n%s\n", (item->email->htmlbody_was_unicode) ? "unicode" : "sbcs", - item->email->htmlbody)); + LIST_COPY_EMAIL_STR("HTML body", item->email->htmlbody); break; case 0x1035: // Message ID - DEBUG_EMAIL(("Message ID - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->messageid, (char*)); - DEBUG_EMAIL(("%s\n", item->email->messageid)); + LIST_COPY_EMAIL_STR("Message ID", item->email->messageid); break; case 0x1042: // in-reply-to - DEBUG_EMAIL(("In-Reply-To - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->in_reply_to, (char*)); - DEBUG_EMAIL(("%s\n", item->email->in_reply_to)); + LIST_COPY_EMAIL_STR("In-Reply-To", item->email->in_reply_to); break; case 0x1046: // Return Path - this seems to be the message-id of the rfc822 mail that is being returned - DEBUG_EMAIL(("Return Path - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->return_path_address, (char*)); - DEBUG_EMAIL(("%s\n", item->email->return_path_address)); + LIST_COPY_EMAIL_STR("Return Path", item->email->return_path_address); break; case 0x3001: // PR_DISPLAY_NAME File As - DEBUG_EMAIL(("Display Name - ")); - LIST_COPY(item->file_as, (char*)); - DEBUG_EMAIL(("%s\n", item->file_as)); + LIST_COPY_STR("Display Name", item->file_as); break; case 0x3002: // PR_ADDRTYPE - DEBUG_EMAIL(("Address Type - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->address1_transport, (char*)); - DEBUG_EMAIL(("|%s|\n", item->contact->address1_transport)); + LIST_COPY_CONTACT_STR("Address Type", item->contact->address1_transport); break; case 0x3003: // PR_EMAIL_ADDRESS - // Contact's email address - DEBUG_EMAIL(("Contact Address - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->address1, (char*)); - DEBUG_EMAIL(("|%s|\n", item->contact->address1)); + LIST_COPY_CONTACT_STR("Contact email Address", item->contact->address1); break; case 0x3004: // PR_COMMENT Comment for item - usually folders - DEBUG_EMAIL(("Comment - ")); - LIST_COPY(item->comment, (char*)); - DEBUG_EMAIL(("%s\n", item->comment)); + LIST_COPY_STR("Comment", item->comment); break; case 0x3007: // PR_CREATION_TIME Date 4 - Creation Date? DEBUG_EMAIL(("Date 4 (Item Creation Date) - ")); @@ -2532,15 +2350,8 @@ DEBUG_EMAIL(("%i\n", item->folder->unseen_email_count)); break; case 0x360A: // PR_SUBFOLDERS Has children - DEBUG_EMAIL(("Has Subfolders - ")); MALLOC_FOLDER(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->folder->subfolder = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->folder->subfolder = 0; - } + LIST_COPY_BOOL("Has Subfolders", item->folder->subfolder); break; case 0x3613: // PR_CONTAINER_CLASS IPF.x DEBUG_EMAIL(("IPF.x - ")); @@ -2585,10 +2396,8 @@ } break; case 0x3704: // PR_ATTACH_FILENAME Attachment filename (8.3) - DEBUG_EMAIL(("Attachment Filename - ")); NULL_CHECK(attach); - LIST_COPY(attach->filename1, (char*)); - DEBUG_EMAIL(("%s\n", attach->filename1)); + LIST_COPY_STR("Attachment Filename", attach->filename1); break; case 0x3705: // PR_ATTACH_METHOD // 0 - No Attachment @@ -2611,10 +2420,8 @@ (t==5?"Embedded Message":"OLE")))))),t)); break; case 0x3707: // PR_ATTACH_LONG_FILENAME Attachment filename (long?) - DEBUG_EMAIL(("Attachment Filename long - ")); NULL_CHECK(attach); - LIST_COPY(attach->filename2, (char*)); - DEBUG_EMAIL(("%s\n", attach->filename2)); + LIST_COPY_STR("Attachment Filename long", attach->filename2); break; case 0x370B: // PR_RENDERING_POSITION // position in characters that the attachment appears in the plain text body @@ -2625,10 +2432,8 @@ DEBUG_EMAIL(("%i [%#x]\n", attach->position)); break; case 0x370E: // PR_ATTACH_MIME_TAG Mime type of encoding - DEBUG_EMAIL(("Attachment mime encoding - ")); NULL_CHECK(attach); - LIST_COPY(attach->mimetype, (char*)); - DEBUG_EMAIL(("%s\n", attach->mimetype)); + LIST_COPY_STR("Attachment mime encoding", attach->mimetype); break; case 0x3710: // PR_ATTACH_MIME_SEQUENCE // sequence number for mime parts. Includes body @@ -2639,113 +2444,55 @@ DEBUG_EMAIL(("%i\n", attach->sequence)); break; case 0x3A00: // PR_ACCOUNT - DEBUG_EMAIL(("Contact's Account name - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->account_name, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->account_name)); + LIST_COPY_CONTACT_STR("Contact's Account name", item->contact->account_name); break; case 0x3A01: // PR_ALTERNATE_RECIPIENT DEBUG_EMAIL(("Contact Alternate Recipient - NOT PROCESSED\n")); break; case 0x3A02: // PR_CALLBACK_TELEPHONE_NUMBER - DEBUG_EMAIL(("Callback telephone number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->callback_phone, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->callback_phone)); + LIST_COPY_CONTACT_STR("Callback telephone number", item->contact->callback_phone); break; case 0x3A03: // PR_CONVERSION_PROHIBITED - DEBUG_EMAIL(("Message Conversion Prohibited - ")); - MALLOC_EMAIL(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->email->conversion_prohib = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->email->conversion_prohib = 0; - } + LIST_COPY_EMAIL_BOOL("Message Conversion Prohibited", item->email->conversion_prohibited); break; case 0x3A05: // PR_GENERATION suffix - DEBUG_EMAIL(("Contacts Suffix - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->suffix, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->suffix)); + LIST_COPY_CONTACT_STR("Contacts Suffix", item->contact->suffix); break; case 0x3A06: // PR_GIVEN_NAME Contact's first name - DEBUG_EMAIL(("Contacts First Name - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->first_name, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->first_name)); + LIST_COPY_CONTACT_STR("Contacts First Name", item->contact->first_name); break; case 0x3A07: // PR_GOVERNMENT_ID_NUMBER - DEBUG_EMAIL(("Contacts Government ID Number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->gov_id, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->gov_id)); + LIST_COPY_CONTACT_STR("Contacts Government ID Number", item->contact->gov_id); break; case 0x3A08: // PR_BUSINESS_TELEPHONE_NUMBER - DEBUG_EMAIL(("Business Telephone Number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->business_phone, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->business_phone)); + LIST_COPY_CONTACT_STR("Business Telephone Number", item->contact->business_phone); break; case 0x3A09: // PR_HOME_TELEPHONE_NUMBER - DEBUG_EMAIL(("Home Telephone Number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->home_phone, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->home_phone)); + LIST_COPY_CONTACT_STR("Home Telephone Number", item->contact->home_phone); break; case 0x3A0A: // PR_INITIALS Contact's Initials - DEBUG_EMAIL(("Contacts Initials - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->initials, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->initials)); + LIST_COPY_CONTACT_STR("Contacts Initials", item->contact->initials); break; case 0x3A0B: // PR_KEYWORD - DEBUG_EMAIL(("Keyword - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->keyword, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->keyword)); + LIST_COPY_CONTACT_STR("Keyword", item->contact->keyword); break; case 0x3A0C: // PR_LANGUAGE - DEBUG_EMAIL(("Contact's Language - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->language, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->language)); + LIST_COPY_CONTACT_STR("Contact's Language", item->contact->language); break; case 0x3A0D: // PR_LOCATION - DEBUG_EMAIL(("Contact's Location - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->location, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->location)); + LIST_COPY_CONTACT_STR("Contact's Location", item->contact->location); break; case 0x3A0E: // PR_MAIL_PERMISSION - Can the recipient receive and send email - DEBUG_EMAIL(("Mail Permission - ")); - MALLOC_CONTACT(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->contact->mail_permission = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->contact->mail_permission = 0; - } + LIST_COPY_CONTACT_BOOL("Mail Permission", item->contact->mail_permission); break; case 0x3A0F: // PR_MHS_COMMON_NAME - DEBUG_EMAIL(("MHS Common Name - ")); - MALLOC_EMAIL(item); - LIST_COPY(item->email->common_name, (char*)); - DEBUG_EMAIL(("%s\n", item->email->common_name)); + LIST_COPY_CONTACT_STR("MHS Common Name", item->contact->common_name); break; case 0x3A10: // PR_ORGANIZATIONAL_ID_NUMBER - DEBUG_EMAIL(("Organizational ID # - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->org_id, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->org_id)); + LIST_COPY_CONTACT_STR("Organizational ID #", item->contact->org_id); break; case 0x3A11: // PR_SURNAME Contact's Surname - DEBUG_EMAIL(("Contacts Surname - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->surname, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->surname)); + LIST_COPY_CONTACT_STR("Contacts Surname", item->contact->surname); break; case 0x3A12: // PR_ORIGINAL_ENTRY_ID DEBUG_EMAIL(("Original Entry ID - NOT PROCESSED\n")); @@ -2757,180 +2504,91 @@ DEBUG_EMAIL(("Original Search Key - NOT PROCESSED\n")); break; case 0x3A15: // PR_POSTAL_ADDRESS - DEBUG_EMAIL(("Default Postal Address - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->def_postal_address, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->def_postal_address)); + LIST_COPY_CONTACT_STR("Default Postal Address", item->contact->def_postal_address); break; case 0x3A16: // PR_COMPANY_NAME - DEBUG_EMAIL(("Company Name - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->company_name, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->company_name)); + LIST_COPY_CONTACT_STR("Company Name", item->contact->company_name); break; case 0x3A17: // PR_TITLE - Job Title - DEBUG_EMAIL(("Job Title - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->job_title, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->job_title)); + LIST_COPY_CONTACT_STR("Job Title", item->contact->job_title); break; case 0x3A18: // PR_DEPARTMENT_NAME - DEBUG_EMAIL(("Department Name - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->department, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->department)); + LIST_COPY_CONTACT_STR("Department Name", item->contact->department); break; case 0x3A19: // PR_OFFICE_LOCATION - DEBUG_EMAIL(("Office Location - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->office_loc, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->office_loc)); + LIST_COPY_CONTACT_STR("Office Location", item->contact->office_loc); break; case 0x3A1A: // PR_PRIMARY_TELEPHONE_NUMBER - DEBUG_EMAIL(("Primary Telephone - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->primary_phone, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->primary_phone)); + LIST_COPY_CONTACT_STR("Primary Telephone", item->contact->primary_phone); break; case 0x3A1B: // PR_BUSINESS2_TELEPHONE_NUMBER - DEBUG_EMAIL(("Business Phone Number 2 - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->business_phone2, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->business_phone2)); + LIST_COPY_CONTACT_STR("Business Phone Number 2", item->contact->business_phone2); break; case 0x3A1C: // PR_MOBILE_TELEPHONE_NUMBER - DEBUG_EMAIL(("Mobile Phone Number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->mobile_phone, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->mobile_phone)); + LIST_COPY_CONTACT_STR("Mobile Phone Number", item->contact->mobile_phone); break; case 0x3A1D: // PR_RADIO_TELEPHONE_NUMBER - DEBUG_EMAIL(("Radio Phone Number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->radio_phone, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->radio_phone)); + LIST_COPY_CONTACT_STR("Radio Phone Number", item->contact->radio_phone); break; case 0x3A1E: // PR_CAR_TELEPHONE_NUMBER - DEBUG_EMAIL(("Car Phone Number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->car_phone, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->car_phone)); + LIST_COPY_CONTACT_STR("Car Phone Number", item->contact->car_phone); break; case 0x3A1F: // PR_OTHER_TELEPHONE_NUMBER - DEBUG_EMAIL(("Other Phone Number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->other_phone, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->other_phone)); + LIST_COPY_CONTACT_STR("Other Phone Number", item->contact->other_phone); break; case 0x3A20: // PR_TRANSMITTABLE_DISPLAY_NAME - DEBUG_EMAIL(("Transmittable Display Name - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->transmittable_display_name, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->transmittable_display_name)); + LIST_COPY_CONTACT_STR("Transmittable Display Name", item->contact->transmittable_display_name); break; case 0x3A21: // PR_PAGER_TELEPHONE_NUMBER - DEBUG_EMAIL(("Pager Phone Number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->pager_phone, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->pager_phone)); + LIST_COPY_CONTACT_STR("Pager Phone Number", item->contact->pager_phone); break; case 0x3A22: // PR_USER_CERTIFICATE DEBUG_EMAIL(("User Certificate - NOT PROCESSED")); break; case 0x3A23: // PR_PRIMARY_FAX_NUMBER - DEBUG_EMAIL(("Primary Fax Number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->primary_fax, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->primary_fax)); + LIST_COPY_CONTACT_STR("Primary Fax Number", item->contact->primary_fax); break; case 0x3A24: // PR_BUSINESS_FAX_NUMBER - DEBUG_EMAIL(("Business Fax Number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->business_fax, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->business_fax)); + LIST_COPY_CONTACT_STR("Business Fax Number", item->contact->business_fax); break; case 0x3A25: // PR_HOME_FAX_NUMBER - DEBUG_EMAIL(("Home Fax Number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->home_fax, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->home_fax)); + LIST_COPY_CONTACT_STR("Home Fax Number", item->contact->home_fax); break; case 0x3A26: // PR_BUSINESS_ADDRESS_COUNTRY - DEBUG_EMAIL(("Business Address Country - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->business_country, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->business_country)); + LIST_COPY_CONTACT_STR("Business Address Country", item->contact->business_country); break; case 0x3A27: // PR_BUSINESS_ADDRESS_CITY - DEBUG_EMAIL(("Business Address City - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->business_city, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->business_city)); + LIST_COPY_CONTACT_STR("Business Address City", item->contact->business_city); break; case 0x3A28: // PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE - DEBUG_EMAIL(("Business Address State - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->business_state, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->business_state)); + LIST_COPY_CONTACT_STR("Business Address State", item->contact->business_state); break; case 0x3A29: // PR_BUSINESS_ADDRESS_STREET - DEBUG_EMAIL(("Business Address Street - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->business_street, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->business_street)); + LIST_COPY_CONTACT_STR("Business Address Street", item->contact->business_street); break; case 0x3A2A: // PR_BUSINESS_POSTAL_CODE - DEBUG_EMAIL(("Business Postal Code - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->business_postal_code, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->business_postal_code)); + LIST_COPY_CONTACT_STR("Business Postal Code", item->contact->business_postal_code); break; case 0x3A2B: // PR_BUSINESS_PO_BOX - DEBUG_EMAIL(("Business PO Box - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->business_po_box, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->business_po_box)); + LIST_COPY_CONTACT_STR("Business PO Box", item->contact->business_po_box); break; case 0x3A2C: // PR_TELEX_NUMBER - DEBUG_EMAIL(("Telex Number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->telex, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->telex)); + LIST_COPY_CONTACT_STR("Telex Number", item->contact->telex); break; case 0x3A2D: // PR_ISDN_NUMBER - DEBUG_EMAIL(("ISDN Number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->isdn_phone, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->isdn_phone)); + LIST_COPY_CONTACT_STR("ISDN Number", item->contact->isdn_phone); break; case 0x3A2E: // PR_ASSISTANT_TELEPHONE_NUMBER - DEBUG_EMAIL(("Assistant Phone Number - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->assistant_phone, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->assistant_phone)); + LIST_COPY_CONTACT_STR("Assistant Phone Number", item->contact->assistant_phone); break; case 0x3A2F: // PR_HOME2_TELEPHONE_NUMBER - DEBUG_EMAIL(("Home Phone 2 - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->home_phone2, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->home_phone2)); + LIST_COPY_CONTACT_STR("Home Phone 2", item->contact->home_phone2); break; case 0x3A30: // PR_ASSISTANT - DEBUG_EMAIL(("Assistant's Name - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->assistant_name, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->assistant_name)); + LIST_COPY_CONTACT_STR("Assistant's Name", item->contact->assistant_name); break; case 0x3A40: // PR_SEND_RICH_INFO - DEBUG_EMAIL(("Can receive Rich Text - ")); - MALLOC_CONTACT(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->contact->rich_text = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->contact->rich_text = 0; - } + LIST_COPY_CONTACT_BOOL("Can receive Rich Text", item->contact->rich_text); break; case 0x3A41: // PR_WEDDING_ANNIVERSARY DEBUG_EMAIL(("Wedding Anniversary - ")); @@ -2945,64 +2603,34 @@ DEBUG_EMAIL(("%s\n", fileTimeToAscii(item->contact->birthday))); break; case 0x3A43: // PR_HOBBIES - DEBUG_EMAIL(("Hobbies - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->hobbies, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->hobbies)); + LIST_COPY_CONTACT_STR("Hobbies", item->contact->hobbies); break; case 0x3A44: // PR_MIDDLE_NAME - DEBUG_EMAIL(("Middle Name - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->middle_name, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->middle_name)); + LIST_COPY_CONTACT_STR("Middle Name", item->contact->middle_name); break; case 0x3A45: // PR_DISPLAY_NAME_PREFIX - DEBUG_EMAIL(("Display Name Prefix (Title) - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->display_name_prefix, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->display_name_prefix)); + LIST_COPY_CONTACT_STR("Display Name Prefix (Title)", item->contact->display_name_prefix); break; case 0x3A46: // PR_PROFESSION - DEBUG_EMAIL(("Profession - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->profession, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->profession)); + LIST_COPY_CONTACT_STR("Profession", item->contact->profession); break; case 0x3A47: // PR_PREFERRED_BY_NAME - DEBUG_EMAIL(("Preferred By Name - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->pref_name, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->pref_name)); + LIST_COPY_CONTACT_STR("Preferred By Name", item->contact->pref_name); break; case 0x3A48: // PR_SPOUSE_NAME - DEBUG_EMAIL(("Spouse's Name - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->spouse_name, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->spouse_name)); + LIST_COPY_CONTACT_STR("Spouse's Name", item->contact->spouse_name); break; case 0x3A49: // PR_COMPUTER_NETWORK_NAME - DEBUG_EMAIL(("Computer Network Name - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->computer_name, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->computer_name)); + LIST_COPY_CONTACT_STR("Computer Network Name", item->contact->computer_name); break; case 0x3A4A: // PR_CUSTOMER_ID - DEBUG_EMAIL(("Customer ID - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->customer_id, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->customer_id)); + LIST_COPY_CONTACT_STR("Customer ID", item->contact->customer_id); break; case 0x3A4B: // PR_TTYTDD_PHONE_NUMBER - DEBUG_EMAIL(("TTY/TDD Phone - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->ttytdd_phone, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->ttytdd_phone)); + LIST_COPY_CONTACT_STR("TTY/TDD Phone", item->contact->ttytdd_phone); break; case 0x3A4C: // PR_FTP_SITE - DEBUG_EMAIL(("Ftp Site - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->ftp_site, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->ftp_site)); + LIST_COPY_CONTACT_STR("Ftp Site", item->contact->ftp_site); break; case 0x3A4D: // PR_GENDER DEBUG_EMAIL(("Gender - ")); @@ -3024,109 +2652,58 @@ } break; case 0x3A4E: // PR_MANAGER_NAME - DEBUG_EMAIL(("Manager's Name - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->manager_name, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->manager_name)); + LIST_COPY_CONTACT_STR("Manager's Name", item->contact->manager_name); break; case 0x3A4F: // PR_NICKNAME - DEBUG_EMAIL(("Nickname - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->nickname, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->nickname)); + LIST_COPY_CONTACT_STR("Nickname", item->contact->nickname); break; case 0x3A50: // PR_PERSONAL_HOME_PAGE - DEBUG_EMAIL(("Personal Home Page - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->personal_homepage, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->personal_homepage)); + LIST_COPY_CONTACT_STR("Personal Home Page", item->contact->personal_homepage); break; case 0x3A51: // PR_BUSINESS_HOME_PAGE - DEBUG_EMAIL(("Business Home Page - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->business_homepage, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->business_homepage)); + LIST_COPY_CONTACT_STR("Business Home Page", item->contact->business_homepage); break; case 0x3A57: // PR_COMPANY_MAIN_PHONE_NUMBER - DEBUG_EMAIL(("Company Main Phone - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->company_main_phone, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->company_main_phone)); + LIST_COPY_CONTACT_STR("Company Main Phone", item->contact->company_main_phone); break; case 0x3A58: // PR_CHILDRENS_NAMES DEBUG_EMAIL(("Children's Names - NOT PROCESSED\n")); break; case 0x3A59: // PR_HOME_ADDRESS_CITY - DEBUG_EMAIL(("Home Address City - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->home_city, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->home_city)); + LIST_COPY_CONTACT_STR("Home Address City", item->contact->home_city); break; case 0x3A5A: // PR_HOME_ADDRESS_COUNTRY - DEBUG_EMAIL(("Home Address Country - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->home_country, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->home_country)); + LIST_COPY_CONTACT_STR("Home Address Country", item->contact->home_country); break; case 0x3A5B: // PR_HOME_ADDRESS_POSTAL_CODE - DEBUG_EMAIL(("Home Address Postal Code - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->home_postal_code, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->home_postal_code)); + LIST_COPY_CONTACT_STR("Home Address Postal Code", item->contact->home_postal_code); break; case 0x3A5C: // PR_HOME_ADDRESS_STATE_OR_PROVINCE - DEBUG_EMAIL(("Home Address State or Province - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->home_state, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->home_state)); + LIST_COPY_CONTACT_STR("Home Address State or Province", item->contact->home_state); break; case 0x3A5D: // PR_HOME_ADDRESS_STREET - DEBUG_EMAIL(("Home Address Street - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->home_street, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->home_street)); + LIST_COPY_CONTACT_STR("Home Address Street", item->contact->home_street); break; case 0x3A5E: // PR_HOME_ADDRESS_POST_OFFICE_BOX - DEBUG_EMAIL(("Home Address Post Office Box - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->home_po_box, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->home_po_box)); + LIST_COPY_CONTACT_STR("Home Address Post Office Box", item->contact->home_po_box); break; case 0x3A5F: // PR_OTHER_ADDRESS_CITY - DEBUG_EMAIL(("Other Address City - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->other_city, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->other_city)); + LIST_COPY_CONTACT_STR("Other Address City", item->contact->other_city); break; case 0x3A60: // PR_OTHER_ADDRESS_COUNTRY - DEBUG_EMAIL(("Other Address Country - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->other_country, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->other_country)); + LIST_COPY_CONTACT_STR("Other Address Country", item->contact->other_country); break; case 0x3A61: // PR_OTHER_ADDRESS_POSTAL_CODE - DEBUG_EMAIL(("Other Address Postal Code - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->other_postal_code, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->other_postal_code)); + LIST_COPY_CONTACT_STR("Other Address Postal Code", item->contact->other_postal_code); break; case 0x3A62: // PR_OTHER_ADDRESS_STATE_OR_PROVINCE - DEBUG_EMAIL(("Other Address State - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->other_state, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->other_state)); + LIST_COPY_CONTACT_STR("Other Address State", item->contact->other_state); break; case 0x3A63: // PR_OTHER_ADDRESS_STREET - DEBUG_EMAIL(("Other Address Street - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->other_street, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->other_street)); + LIST_COPY_CONTACT_STR("Other Address Street", item->contact->other_street); break; case 0x3A64: // PR_OTHER_ADDRESS_POST_OFFICE_BOX - DEBUG_EMAIL(("Other Address Post Office box - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->other_po_box, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->other_po_box)); + LIST_COPY_CONTACT_STR("Other Address Post Office box", item->contact->other_po_box); break; case 0x3FDE: // PR_INTERNET_CPID memcpy(&(item->internet_cpid), list->items[x]->data, sizeof(item->internet_cpid)); @@ -3191,142 +2768,73 @@ DEBUG_EMAIL_HEXPRINT((char*)item->message_store->top_of_folder->entryid, 16); break; case 0x8005: // Contact's Fullname - DEBUG_EMAIL(("Contact Fullname - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->fullname, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->fullname)); + LIST_COPY_CONTACT_STR("Contact Fullname", item->contact->fullname); break; case 0x801A: // Full Home Address - DEBUG_EMAIL(("Home Address - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->home_address, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->home_address)); + LIST_COPY_CONTACT_STR("Home Address", item->contact->home_address); break; case 0x801B: // Full Business Address - DEBUG_EMAIL(("Business Address - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->business_address, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->business_address)); + LIST_COPY_CONTACT_STR("Business Address", item->contact->business_address); break; case 0x801C: // Full Other Address - DEBUG_EMAIL(("Other Address - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->other_address, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->other_address)); + LIST_COPY_CONTACT_STR("Other Address", item->contact->other_address); break; case 0x8045: // Work address street - DEBUG_EMAIL(("Work address street - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->work_address_street, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->work_address_street)); + LIST_COPY_CONTACT_STR("Work address street", item->contact->work_address_street); break; case 0x8046: // Work address city - DEBUG_EMAIL(("Work address city - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->work_address_city, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->work_address_city)); + LIST_COPY_CONTACT_STR("Work address city", item->contact->work_address_city); break; case 0x8047: // Work address state - DEBUG_EMAIL(("Work address state - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->work_address_state, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->work_address_state)); + LIST_COPY_CONTACT_STR("Work address state", item->contact->work_address_state); break; case 0x8048: // Work address postalcode - DEBUG_EMAIL(("Work address postalcode - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->work_address_postalcode, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->work_address_postalcode)); + LIST_COPY_CONTACT_STR("Work address postalcode", item->contact->work_address_postalcode); break; case 0x8049: // Work address country - DEBUG_EMAIL(("Work address country - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->work_address_country, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->work_address_country)); + LIST_COPY_CONTACT_STR("Work address country", item->contact->work_address_country); break; case 0x804A: // Work address postofficebox - DEBUG_EMAIL(("Work address postofficebox - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->work_address_postofficebox, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->work_address_postofficebox)); + LIST_COPY_CONTACT_STR("Work address postofficebox", item->contact->work_address_postofficebox); break; case 0x8082: // Email Address 1 Transport - DEBUG_EMAIL(("Email Address 1 Transport - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->address1_transport, (char*)); - DEBUG_EMAIL(("|%s|\n", item->contact->address1_transport)); + LIST_COPY_CONTACT_STR("Email Address 1 Transport", item->contact->address1_transport); break; case 0x8083: // Email Address 1 Address - DEBUG_EMAIL(("Email Address 1 Address - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->address1, (char*)); - DEBUG_EMAIL(("|%s|\n", item->contact->address1)); + LIST_COPY_CONTACT_STR("Email Address 1 Address", item->contact->address1); break; case 0x8084: // Email Address 1 Description - DEBUG_EMAIL(("Email Address 1 Description - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->address1_desc, (char*)); - DEBUG_EMAIL(("|%s|\n", item->contact->address1_desc)); + LIST_COPY_CONTACT_STR("Email Address 1 Description", item->contact->address1_desc); break; case 0x8085: // Email Address 1 Record - DEBUG_EMAIL(("Email Address 1 Record - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->address1a, (char*)); - DEBUG_EMAIL(("|%s|\n", item->contact->address1a)); + LIST_COPY_CONTACT_STR("Email Address 1 Record", item->contact->address1a); break; case 0x8092: // Email Address 2 Transport - DEBUG_EMAIL(("Email Address 2 Transport - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->address2_transport, (char*)); - DEBUG_EMAIL(("|%s|\n", item->contact->address2_transport)); + LIST_COPY_CONTACT_STR("Email Address 2 Transport", item->contact->address2_transport); break; case 0x8093: // Email Address 2 Address - DEBUG_EMAIL(("Email Address 2 Address - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->address2, (char*)); - DEBUG_EMAIL(("|%s|\n", item->contact->address2)); + LIST_COPY_CONTACT_STR("Email Address 2 Address", item->contact->address2); break; case 0x8094: // Email Address 2 Description - DEBUG_EMAIL (("Email Address 2 Description - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->address2_desc, (char*)); - DEBUG_EMAIL(("|%s|\n", item->contact->address2_desc)); + LIST_COPY_CONTACT_STR("Email Address 2 Description", item->contact->address2_desc); break; case 0x8095: // Email Address 2 Record - DEBUG_EMAIL(("Email Address 2 Record - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->address2a, (char*)); - DEBUG_EMAIL(("|%s|\n", item->contact->address2a)); + LIST_COPY_CONTACT_STR("Email Address 2 Record", item->contact->address2a); break; case 0x80A2: // Email Address 3 Transport - DEBUG_EMAIL (("Email Address 3 Transport - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->address3_transport, (char*)); - DEBUG_EMAIL(("|%s|\n", item->contact->address3_transport)); + LIST_COPY_CONTACT_STR("Email Address 3 Transport", item->contact->address3_transport); break; case 0x80A3: // Email Address 3 Address - DEBUG_EMAIL(("Email Address 3 Address - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->address3, (char*)); - DEBUG_EMAIL(("|%s|\n", item->contact->address3)); + LIST_COPY_CONTACT_STR("Email Address 3 Address", item->contact->address3); break; case 0x80A4: // Email Address 3 Description - DEBUG_EMAIL(("Email Address 3 Description - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->address3_desc, (char*)); - DEBUG_EMAIL(("|%s|\n", item->contact->address3_desc)); + LIST_COPY_CONTACT_STR("Email Address 3 Description", item->contact->address3_desc); break; case 0x80A5: // Email Address 3 Record - DEBUG_EMAIL(("Email Address 3 Record - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->address3a, (char*)); - DEBUG_EMAIL(("|%s|\n", item->contact->address3a)); + LIST_COPY_CONTACT_STR("Email Address 3 Record", item->contact->address3a); break; case 0x80D8: // Internet Free/Busy - DEBUG_EMAIL(("Internet Free/Busy - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->free_busy_address, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->free_busy_address)); + LIST_COPY_CONTACT_STR("Internet Free/Busy", item->contact->free_busy_address); break; case 0x8205: // Show on Free/Busy as // 0: Free @@ -3351,10 +2859,7 @@ } break; case 0x8208: // Location of an appointment - DEBUG_EMAIL(("Appointment Location - ")); - MALLOC_APPOINTMENT(item); - LIST_COPY(item->appointment->location, (char*)); - DEBUG_EMAIL(("%s\n", item->appointment->location)); + LIST_COPY_APPT_STR("Appointment Location", item->appointment->location); break; case 0x820d: // Appointment start DEBUG_EMAIL(("Appointment Date Start - ")); @@ -3399,15 +2904,7 @@ } break; case 0x8215: // All day appointment flag - DEBUG_EMAIL(("All day flag - ")); - MALLOC_APPOINTMENT(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->appointment->all_day = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->appointment->all_day = 0; - } + LIST_COPY_APPT_BOOL("All day flag", item->appointment->all_day); break; case 0x8231: // Recurrence type // 1: Daily @@ -3432,16 +2929,10 @@ } break; case 0x8232: // Recurrence description - DEBUG_EMAIL(("Appointment recurrence description - ")); - MALLOC_APPOINTMENT(item); - LIST_COPY(item->appointment->recurrence, (char*)); - DEBUG_EMAIL(("%s\n", item->appointment->recurrence)); + LIST_COPY_APPT_STR("Appointment recurrence description", item->appointment->recurrence); break; case 0x8234: // TimeZone as String - DEBUG_EMAIL(("TimeZone of times - ")); - MALLOC_APPOINTMENT(item); - LIST_COPY(item->appointment->timezonestring, (char*)); - DEBUG_EMAIL(("%s\n", item->appointment->timezonestring)); + LIST_COPY_APPT_STR("TimeZone of times", item->appointment->timezonestring); break; case 0x8235: // Recurrence start date DEBUG_EMAIL(("Recurrence Start Date - ")); @@ -3463,15 +2954,7 @@ DEBUG_EMAIL(("%i\n", item->appointment->alarm_minutes)); break; case 0x8503: // Reminder alarm - DEBUG_EMAIL(("Reminder alarm - ")); - MALLOC_APPOINTMENT(item); - if (*(int16_t*)list->items[x]->data) { - DEBUG_EMAIL(("True\n")); - item->appointment->alarm = 1; - } else { - DEBUG_EMAIL(("False\n")); - item->appointment->alarm = 0; - } + LIST_COPY_APPT_BOOL("Reminder alarm", item->appointment->alarm); break; case 0x8516: // Common start DEBUG_EMAIL(("Common Start Date - ")); @@ -3482,33 +2965,19 @@ DEBUG_EMAIL(("%s\n", fileTimeToAscii((FILETIME*)list->items[x]->data))); break; case 0x851f: // Play reminder sound filename - DEBUG_EMAIL(("Appointment reminder sound filename - ")); - MALLOC_APPOINTMENT(item); - LIST_COPY(item->appointment->alarm_filename, (char*)); - DEBUG_EMAIL(("%s\n", item->appointment->alarm_filename)); + LIST_COPY_APPT_STR("Appointment reminder sound filename", item->appointment->alarm_filename); break; case 0x8530: // Followup - DEBUG_EMAIL(("Followup String - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->followup, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->followup)); + LIST_COPY_CONTACT_STR("Followup String", item->contact->followup); break; case 0x8534: // Mileage - DEBUG_EMAIL(("Mileage - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->mileage, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->mileage)); + LIST_COPY_CONTACT_STR("Mileage", item->contact->mileage); break; case 0x8535: // Billing Information - DEBUG_EMAIL(("Billing Information - ")); - MALLOC_CONTACT(item); - LIST_COPY(item->contact->billing_information, (char*)); - DEBUG_EMAIL(("%s\n", item->contact->billing_information)); + LIST_COPY_CONTACT_STR("Billing Information", item->contact->billing_information); break; case 0x8554: // Outlook Version - DEBUG_EMAIL(("Outlook Version - ")); - LIST_COPY(item->outlook_version, (char*)); - DEBUG_EMAIL(("%s\n", item->outlook_version)); + LIST_COPY_STR("Outlook Version", item->outlook_version); break; case 0x8560: // Appointment Reminder Time DEBUG_EMAIL(("Appointment Reminder Time - ")); @@ -3517,10 +2986,8 @@ DEBUG_EMAIL(("%s\n", fileTimeToAscii(item->appointment->reminder))); break; case 0x8700: // Journal Type - DEBUG_EMAIL(("Journal Entry Type - ")); MALLOC_JOURNAL(item); - LIST_COPY(item->journal->type, (char*)); - DEBUG_EMAIL(("%s\n", item->journal->type)); + LIST_COPY_STR("Journal Entry Type", item->journal->type); break; case 0x8706: // Journal Start date/time DEBUG_EMAIL(("Start Timestamp - ")); @@ -3535,10 +3002,8 @@ DEBUG_EMAIL(("%s\n", fileTimeToAscii(item->journal->end))); break; case 0x8712: // Title? - DEBUG_EMAIL(("Journal Entry Type - ")); MALLOC_JOURNAL(item); - LIST_COPY(item->journal->type, (char*)); - DEBUG_EMAIL(("%s\n", item->journal->type)); + LIST_COPY_STR("Journal Entry Type", item->journal->type); break; default: if (list->items[x]->type == (uint32_t)0x0002) { @@ -3647,7 +3112,6 @@ list->items[x]->data = NULL; } } - x++; } list = list->next; if (attach) attach = attach->next; @@ -3813,9 +3277,9 @@ void pst_free_attach(pst_item_attach *attach) { while (attach) { pst_item_attach *t; - SAFE_FREE(attach->filename1); - SAFE_FREE(attach->filename2); - SAFE_FREE(attach->mimetype); + SAFE_FREE_STR(attach->filename1); + SAFE_FREE_STR(attach->filename2); + SAFE_FREE_STR(attach->mimetype); SAFE_FREE(attach->data); pst_free_id2(attach->id2_head); t = attach->next; @@ -3832,47 +3296,42 @@ if (item) { if (item->email) { SAFE_FREE(item->email->arrival_date); - SAFE_FREE(item->email->body); - SAFE_FREE(item->email->cc_address); - SAFE_FREE(item->email->bcc_address); - SAFE_FREE(item->email->common_name); + SAFE_FREE_STR(item->email->cc_address); + SAFE_FREE_STR(item->email->bcc_address); SAFE_FREE(item->email->encrypted_body); SAFE_FREE(item->email->encrypted_htmlbody); - SAFE_FREE(item->email->header); - SAFE_FREE(item->email->htmlbody); - SAFE_FREE(item->email->in_reply_to); - SAFE_FREE(item->email->messageid); - SAFE_FREE(item->email->original_bcc); - SAFE_FREE(item->email->original_cc); - SAFE_FREE(item->email->original_to); - SAFE_FREE(item->email->outlook_recipient); - SAFE_FREE(item->email->outlook_recipient_name); - SAFE_FREE(item->email->outlook_recipient2); - SAFE_FREE(item->email->outlook_sender); - SAFE_FREE(item->email->outlook_sender_name); - SAFE_FREE(item->email->outlook_sender2); - SAFE_FREE(item->email->proc_subject); - SAFE_FREE(item->email->recip_access); - SAFE_FREE(item->email->recip_address); - SAFE_FREE(item->email->recip2_access); - SAFE_FREE(item->email->recip2_address); - SAFE_FREE(item->email->reply_to); - SAFE_FREE(item->email->rtf_body_tag); + SAFE_FREE_STR(item->email->header); + SAFE_FREE_STR(item->email->htmlbody); + SAFE_FREE_STR(item->email->in_reply_to); + SAFE_FREE_STR(item->email->messageid); + SAFE_FREE_STR(item->email->original_bcc); + SAFE_FREE_STR(item->email->original_cc); + SAFE_FREE_STR(item->email->original_to); + SAFE_FREE_STR(item->email->outlook_recipient); + SAFE_FREE_STR(item->email->outlook_recipient_name); + SAFE_FREE_STR(item->email->outlook_recipient2); + SAFE_FREE_STR(item->email->outlook_sender); + SAFE_FREE_STR(item->email->outlook_sender_name); + SAFE_FREE_STR(item->email->outlook_sender2); + SAFE_FREE_STR(item->email->processed_subject); + SAFE_FREE_STR(item->email->recip_access); + SAFE_FREE_STR(item->email->recip_address); + SAFE_FREE_STR(item->email->recip2_access); + SAFE_FREE_STR(item->email->recip2_address); + SAFE_FREE_STR(item->email->reply_to); + SAFE_FREE_STR(item->email->rtf_body_tag); SAFE_FREE(item->email->rtf_compressed); - SAFE_FREE(item->email->return_path_address); - SAFE_FREE(item->email->sender_access); - SAFE_FREE(item->email->sender_address); - SAFE_FREE(item->email->sender2_access); - SAFE_FREE(item->email->sender2_address); + SAFE_FREE_STR(item->email->return_path_address); + SAFE_FREE_STR(item->email->sender_access); + SAFE_FREE_STR(item->email->sender_address); + SAFE_FREE_STR(item->email->sender2_access); + SAFE_FREE_STR(item->email->sender2_address); SAFE_FREE(item->email->sent_date); SAFE_FREE(item->email->sentmail_folder); - SAFE_FREE(item->email->sentto_address); - if (item->email->subject) - SAFE_FREE(item->email->subject->subj); - SAFE_FREE(item->email->subject); - SAFE_FREE(item->email->report_text); + SAFE_FREE_STR(item->email->sentto_address); + SAFE_FREE_STR(item->email->report_text); SAFE_FREE(item->email->report_time); - SAFE_FREE(item->email->supplementary_info); + SAFE_FREE_STR(item->email->supplementary_info); free(item->email); } if (item->folder) { @@ -3890,102 +3349,103 @@ free(item->message_store); } if (item->contact) { - SAFE_FREE(item->contact->access_method); - SAFE_FREE(item->contact->account_name); - SAFE_FREE(item->contact->address1); - SAFE_FREE(item->contact->address1a); - SAFE_FREE(item->contact->address1_desc); - SAFE_FREE(item->contact->address1_transport); - SAFE_FREE(item->contact->address2); - SAFE_FREE(item->contact->address2a); - SAFE_FREE(item->contact->address2_desc); - SAFE_FREE(item->contact->address2_transport); - SAFE_FREE(item->contact->address3); - SAFE_FREE(item->contact->address3a); - SAFE_FREE(item->contact->address3_desc); - SAFE_FREE(item->contact->address3_transport); - SAFE_FREE(item->contact->assistant_name); - SAFE_FREE(item->contact->assistant_phone); - SAFE_FREE(item->contact->billing_information); + SAFE_FREE_STR(item->contact->access_method); + SAFE_FREE_STR(item->contact->account_name); + SAFE_FREE_STR(item->contact->address1); + SAFE_FREE_STR(item->contact->address1a); + SAFE_FREE_STR(item->contact->address1_desc); + SAFE_FREE_STR(item->contact->address1_transport); + SAFE_FREE_STR(item->contact->address2); + SAFE_FREE_STR(item->contact->address2a); + SAFE_FREE_STR(item->contact->address2_desc); + SAFE_FREE_STR(item->contact->address2_transport); + SAFE_FREE_STR(item->contact->address3); + SAFE_FREE_STR(item->contact->address3a); + SAFE_FREE_STR(item->contact->address3_desc); + SAFE_FREE_STR(item->contact->address3_transport); + SAFE_FREE_STR(item->contact->assistant_name); + SAFE_FREE_STR(item->contact->assistant_phone); + SAFE_FREE_STR(item->contact->billing_information); SAFE_FREE(item->contact->birthday); - SAFE_FREE(item->contact->business_address); - SAFE_FREE(item->contact->business_city); - SAFE_FREE(item->contact->business_country); - SAFE_FREE(item->contact->business_fax); - SAFE_FREE(item->contact->business_homepage); - SAFE_FREE(item->contact->business_phone); - SAFE_FREE(item->contact->business_phone2); - SAFE_FREE(item->contact->business_po_box); - SAFE_FREE(item->contact->business_postal_code); - SAFE_FREE(item->contact->business_state); - SAFE_FREE(item->contact->business_street); - SAFE_FREE(item->contact->callback_phone); - SAFE_FREE(item->contact->car_phone); - SAFE_FREE(item->contact->company_main_phone); - SAFE_FREE(item->contact->company_name); - SAFE_FREE(item->contact->computer_name); - SAFE_FREE(item->contact->customer_id); - SAFE_FREE(item->contact->def_postal_address); - SAFE_FREE(item->contact->department); - SAFE_FREE(item->contact->display_name_prefix); - SAFE_FREE(item->contact->first_name); - SAFE_FREE(item->contact->followup); - SAFE_FREE(item->contact->free_busy_address); - SAFE_FREE(item->contact->ftp_site); - SAFE_FREE(item->contact->fullname); - SAFE_FREE(item->contact->gov_id); - SAFE_FREE(item->contact->hobbies); - SAFE_FREE(item->contact->home_address); - SAFE_FREE(item->contact->home_city); - SAFE_FREE(item->contact->home_country); - SAFE_FREE(item->contact->home_fax); - SAFE_FREE(item->contact->home_po_box); - SAFE_FREE(item->contact->home_phone); - SAFE_FREE(item->contact->home_phone2); - SAFE_FREE(item->contact->home_postal_code); - SAFE_FREE(item->contact->home_state); - SAFE_FREE(item->contact->home_street); - SAFE_FREE(item->contact->initials); - SAFE_FREE(item->contact->isdn_phone); - SAFE_FREE(item->contact->job_title); - SAFE_FREE(item->contact->keyword); - SAFE_FREE(item->contact->language); - SAFE_FREE(item->contact->location); - SAFE_FREE(item->contact->manager_name); - SAFE_FREE(item->contact->middle_name); - SAFE_FREE(item->contact->mileage); - SAFE_FREE(item->contact->mobile_phone); - SAFE_FREE(item->contact->nickname); - SAFE_FREE(item->contact->office_loc); - SAFE_FREE(item->contact->org_id); - SAFE_FREE(item->contact->other_address); - SAFE_FREE(item->contact->other_city); - SAFE_FREE(item->contact->other_country); - SAFE_FREE(item->contact->other_phone); - SAFE_FREE(item->contact->other_po_box); - SAFE_FREE(item->contact->other_postal_code); - SAFE_FREE(item->contact->other_state); - SAFE_FREE(item->contact->other_street); - SAFE_FREE(item->contact->pager_phone); - SAFE_FREE(item->contact->personal_homepage); - SAFE_FREE(item->contact->pref_name); - SAFE_FREE(item->contact->primary_fax); - SAFE_FREE(item->contact->primary_phone); - SAFE_FREE(item->contact->profession); - SAFE_FREE(item->contact->radio_phone); - SAFE_FREE(item->contact->spouse_name); - SAFE_FREE(item->contact->suffix); - SAFE_FREE(item->contact->surname); - SAFE_FREE(item->contact->telex); - SAFE_FREE(item->contact->transmittable_display_name); - SAFE_FREE(item->contact->ttytdd_phone); + SAFE_FREE_STR(item->contact->business_address); + SAFE_FREE_STR(item->contact->business_city); + SAFE_FREE_STR(item->contact->business_country); + SAFE_FREE_STR(item->contact->business_fax); + SAFE_FREE_STR(item->contact->business_homepage); + SAFE_FREE_STR(item->contact->business_phone); + SAFE_FREE_STR(item->contact->business_phone2); + SAFE_FREE_STR(item->contact->business_po_box); + SAFE_FREE_STR(item->contact->business_postal_code); + SAFE_FREE_STR(item->contact->business_state); + SAFE_FREE_STR(item->contact->business_street); + SAFE_FREE_STR(item->contact->callback_phone); + SAFE_FREE_STR(item->contact->car_phone); + SAFE_FREE_STR(item->contact->company_main_phone); + SAFE_FREE_STR(item->contact->company_name); + SAFE_FREE_STR(item->contact->computer_name); + SAFE_FREE_STR(item->contact->customer_id); + SAFE_FREE_STR(item->contact->def_postal_address); + SAFE_FREE_STR(item->contact->department); + SAFE_FREE_STR(item->contact->display_name_prefix); + SAFE_FREE_STR(item->contact->first_name); + SAFE_FREE_STR(item->contact->followup); + SAFE_FREE_STR(item->contact->free_busy_address); + SAFE_FREE_STR(item->contact->ftp_site); + SAFE_FREE_STR(item->contact->fullname); + SAFE_FREE_STR(item->contact->gov_id); + SAFE_FREE_STR(item->contact->hobbies); + SAFE_FREE_STR(item->contact->home_address); + SAFE_FREE_STR(item->contact->home_city); + SAFE_FREE_STR(item->contact->home_country); + SAFE_FREE_STR(item->contact->home_fax); + SAFE_FREE_STR(item->contact->home_po_box); + SAFE_FREE_STR(item->contact->home_phone); + SAFE_FREE_STR(item->contact->home_phone2); + SAFE_FREE_STR(item->contact->home_postal_code); + SAFE_FREE_STR(item->contact->home_state); + SAFE_FREE_STR(item->contact->home_street); + SAFE_FREE_STR(item->contact->initials); + SAFE_FREE_STR(item->contact->isdn_phone); + SAFE_FREE_STR(item->contact->job_title); + SAFE_FREE_STR(item->contact->keyword); + SAFE_FREE_STR(item->contact->language); + SAFE_FREE_STR(item->contact->location); + SAFE_FREE_STR(item->contact->manager_name); + SAFE_FREE_STR(item->contact->middle_name); + SAFE_FREE_STR(item->contact->mileage); + SAFE_FREE_STR(item->contact->mobile_phone); + SAFE_FREE_STR(item->contact->nickname); + SAFE_FREE_STR(item->contact->office_loc); + SAFE_FREE_STR(item->contact->common_name); + SAFE_FREE_STR(item->contact->org_id); + SAFE_FREE_STR(item->contact->other_address); + SAFE_FREE_STR(item->contact->other_city); + SAFE_FREE_STR(item->contact->other_country); + SAFE_FREE_STR(item->contact->other_phone); + SAFE_FREE_STR(item->contact->other_po_box); + SAFE_FREE_STR(item->contact->other_postal_code); + SAFE_FREE_STR(item->contact->other_state); + SAFE_FREE_STR(item->contact->other_street); + SAFE_FREE_STR(item->contact->pager_phone); + SAFE_FREE_STR(item->contact->personal_homepage); + SAFE_FREE_STR(item->contact->pref_name); + SAFE_FREE_STR(item->contact->primary_fax); + SAFE_FREE_STR(item->contact->primary_phone); + SAFE_FREE_STR(item->contact->profession); + SAFE_FREE_STR(item->contact->radio_phone); + SAFE_FREE_STR(item->contact->spouse_name); + SAFE_FREE_STR(item->contact->suffix); + SAFE_FREE_STR(item->contact->surname); + SAFE_FREE_STR(item->contact->telex); + SAFE_FREE_STR(item->contact->transmittable_display_name); + SAFE_FREE_STR(item->contact->ttytdd_phone); SAFE_FREE(item->contact->wedding_anniversary); - SAFE_FREE(item->contact->work_address_street); - SAFE_FREE(item->contact->work_address_city); - SAFE_FREE(item->contact->work_address_state); - SAFE_FREE(item->contact->work_address_postalcode); - SAFE_FREE(item->contact->work_address_country); - SAFE_FREE(item->contact->work_address_postofficebox); + SAFE_FREE_STR(item->contact->work_address_street); + SAFE_FREE_STR(item->contact->work_address_city); + SAFE_FREE_STR(item->contact->work_address_state); + SAFE_FREE_STR(item->contact->work_address_postalcode); + SAFE_FREE_STR(item->contact->work_address_country); + SAFE_FREE_STR(item->contact->work_address_postofficebox); free(item->contact); } @@ -4001,28 +3461,30 @@ if (item->journal) { SAFE_FREE(item->journal->end); SAFE_FREE(item->journal->start); - SAFE_FREE(item->journal->type); + SAFE_FREE_STR(item->journal->type); free(item->journal); } if (item->appointment) { - SAFE_FREE(item->appointment->location); + SAFE_FREE_STR(item->appointment->location); SAFE_FREE(item->appointment->reminder); - SAFE_FREE(item->appointment->alarm_filename); + SAFE_FREE_STR(item->appointment->alarm_filename); SAFE_FREE(item->appointment->start); SAFE_FREE(item->appointment->end); - SAFE_FREE(item->appointment->timezonestring); - SAFE_FREE(item->appointment->recurrence); + SAFE_FREE_STR(item->appointment->timezonestring); + SAFE_FREE_STR(item->appointment->recurrence); SAFE_FREE(item->appointment->recurrence_start); SAFE_FREE(item->appointment->recurrence_end); free(item->appointment); } SAFE_FREE(item->ascii_type); - SAFE_FREE(item->body_charset); - SAFE_FREE(item->comment); + SAFE_FREE_STR(item->body_charset); + SAFE_FREE_STR(item->body); + SAFE_FREE_STR(item->subject); + SAFE_FREE_STR(item->comment); SAFE_FREE(item->create_date); - SAFE_FREE(item->file_as); + SAFE_FREE_STR(item->file_as); SAFE_FREE(item->modify_date); - SAFE_FREE(item->outlook_version); + SAFE_FREE_STR(item->outlook_version); SAFE_FREE(item->record_key); free(item); } @@ -4787,3 +4249,95 @@ } +/** Convert a code page integer into a string suitable for iconv + * + * @param cp the code page integer used in the pst file + * @return pointer to a static buffer holding the string representation of the + * equivalent iconv character set + */ +const char* codepage(int cp) { + static char buffer[20]; + switch (cp) { + case 932 : return "iso-2022-jp"; + case 936 : return "gb2313"; + case 950 : return "big5"; + case 20127 : return "us-ascii"; + case 20269 : return "iso-6937"; + case 20865 : return "iso-8859-15"; + case 20866 : return "koi8-r"; + case 21866 : return "koi8-u"; + case 28591 : return "iso-8859-1"; + case 28592 : return "iso-8859-2"; + case 28595 : return "iso-8859-5"; + case 28596 : return "iso-8859-6"; + case 28597 : return "iso-8859-7"; + case 28598 : return "iso-8859-8"; + case 28599 : return "iso-8859-9"; + case 50220 : return "iso-2022-jp"; + case 50221 : return "csiso2022jp"; + case 51932 : return "euc-jp"; + case 51949 : return "euc-kr"; + case 65000 : return "utf-7"; + case 65001 : return "utf-8"; + default : + snprintf(buffer, sizeof(buffer), "windows-%d", cp); + return buffer; + } + return NULL; +} + + +/** get the default character set for this item + * @param item pointer to the mapi item of interest + * @return default character set + */ +const char* pst_default_charset(pst_item *item) +{ + return (item->body_charset.str) ? item->body_charset.str : + (item->message_codepage) ? codepage(item->message_codepage) : + (item->internet_cpid) ? codepage(item->internet_cpid) : + "utf-8"; +} + + +/** Convert str to utf8 if possible. Null strings are preserved + * + * @param item pointer to the mapi item of interest + * ¶m str pointer to the mapi string of interest + */ +void pst_convert_utf8_null(pst_item *item, pst_string *str) +{ + if (!str->str) return; + pst_convert_utf8(item, str); +} + + +/** Convert str to utf8 if possible. Null strings are converted into empty strings. + * + * @param item pointer to the mapi item of interest + * ¶m str pointer to the mapi string of interest + */ +void pst_convert_utf8(pst_item *item, pst_string *str) +{ + if (str->is_utf8) return; + if (!str->str) { + str->str = strdup(""); + return; + } + DEBUG_ENT("pst_convert_utf8"); + const char *charset = pst_default_charset(item); + if (!strcasecmp("utf-8", charset)) return; // already utf8 + vbuf *newer = vballoc(2); + size_t rc = vb_8bit2utf8(newer, str->str, strlen(str->str) + 1, charset); + if (rc == (size_t)-1) { + free(newer->b); + DEBUG_EMAIL(("Failed to convert %s to utf-8 - %s\n", charset, str->str)); + } + else { + free(str->str); + str->str = newer->b; + str->is_utf8 = 1; + } + free(newer); + DEBUG_RET(); +} diff -r 06aa84023b48 -r cda7c812ec01 src/libpst.h --- a/src/libpst.h Thu Mar 05 08:23:32 2009 -0800 +++ b/src/libpst.h Sun Mar 08 14:35:26 2009 -0700 @@ -166,23 +166,19 @@ } pst_desc_ll; -typedef struct pst_item_email_subject { - int off1; - int off2; - char *subj; -} pst_item_email_subject; +typedef struct pst_string { + int is_utf8; // 1 = true, 0 = false + char *str; // either utf8 or some sbcs +} pst_string; typedef struct pst_item_email { FILETIME *arrival_date; int autoforward; // 1 = true, 0 = not set, -1 = false - char *body; - int32_t body_was_unicode; // 1 = true, 0 = false - char *cc_address; - char *bcc_address; - char *common_name; + pst_string cc_address; + pst_string bcc_address; int32_t conv_index; - int conversion_prohib; // 1 = true, 0 = false + int conversion_prohibited; // 1 = true, 0 = false int delete_after_submit; // 1 = true, 0 = false int delivery_report; // 1 = true, 0 = false char *encrypted_body; @@ -190,59 +186,56 @@ char *encrypted_htmlbody; size_t encrypted_htmlbody_size; int32_t flag; - char *header; - char *htmlbody; - int32_t htmlbody_was_unicode; // 1 = true, 0 = false + pst_string header; + pst_string htmlbody; int32_t importance; - char *in_reply_to; + pst_string in_reply_to; int message_cc_me; // 1 = true, 0 = false int message_recip_me; // 1 = true, 0 = false int message_to_me; // 1 = true, 0 = false - char *messageid; + pst_string messageid; int32_t orig_sensitivity; - char *original_bcc; - char *original_cc; - char *original_to; - char *outlook_recipient; - char *outlook_recipient_name; - char *outlook_recipient2; - char *outlook_sender; - char *outlook_sender_name; - char *outlook_sender2; + pst_string original_bcc; + pst_string original_cc; + pst_string original_to; + pst_string outlook_recipient; + pst_string outlook_recipient_name; + pst_string outlook_recipient2; + pst_string outlook_sender; + pst_string outlook_sender_name; + pst_string outlook_sender2; int32_t priority; - char *proc_subject; + pst_string processed_subject; int read_receipt; // 1 = true, 0 = false - char *recip_access; - char *recip_address; - char *recip2_access; - char *recip2_address; + pst_string recip_access; + pst_string recip_address; + pst_string recip2_access; + pst_string recip2_address; int reply_requested; // 1 = true, 0 = false - char *reply_to; - char *return_path_address; + pst_string reply_to; + pst_string return_path_address; int32_t rtf_body_char_count; int32_t rtf_body_crc; - char *rtf_body_tag; + pst_string rtf_body_tag; char *rtf_compressed; uint32_t rtf_compressed_size; int rtf_in_sync; // 1 = true, 0 = doesn't exist, -1 = false int32_t rtf_ws_prefix_count; int32_t rtf_ws_trailing_count; - char *sender_access; - char *sender_address; - char *sender2_access; - char *sender2_address; + pst_string sender_access; + pst_string sender_address; + pst_string sender2_access; + pst_string sender2_address; int32_t sensitivity; - FILETIME *sent_date; - pst_entryid *sentmail_folder; - char *sentto_address; - pst_item_email_subject *subject; + FILETIME *sent_date; + pst_entryid *sentmail_folder; + pst_string sentto_address; // delivery report fields - char *report_text; - int32_t report_was_unicode; + pst_string report_text; FILETIME *report_time; int32_t ndr_reason_code; int32_t ndr_diag_code; - char *supplementary_info; + pst_string supplementary_info; int32_t ndr_status_code; } pst_item_email; @@ -270,154 +263,155 @@ typedef struct pst_item_contact { - char *access_method; - char *account_name; - char *address1; - char *address1a; - char *address1_desc; - char *address1_transport; - char *address2; - char *address2a; - char *address2_desc; - char *address2_transport; - char *address3; - char *address3a; - char *address3_desc; - char *address3_transport; - char *assistant_name; - char *assistant_phone; - char *billing_information; - FILETIME *birthday; - char *business_address; // 0x801b - char *business_city; - char *business_country; - char *business_fax; - char *business_homepage; - char *business_phone; - char *business_phone2; - char *business_po_box; - char *business_postal_code; - char *business_state; - char *business_street; - char *callback_phone; - char *car_phone; - char *company_main_phone; - char *company_name; - char *computer_name; - char *customer_id; - char *def_postal_address; - char *department; - char *display_name_prefix; - char *first_name; - char *followup; - char *free_busy_address; - char *ftp_site; - char *fullname; - int16_t gender; - char *gov_id; - char *hobbies; - char *home_address; // 0x801a - char *home_city; - char *home_country; - char *home_fax; - char *home_phone; - char *home_phone2; - char *home_po_box; - char *home_postal_code; - char *home_state; - char *home_street; - char *initials; - char *isdn_phone; - char *job_title; - char *keyword; - char *language; - char *location; - int mail_permission; // 1 = true, 0 = false - char *manager_name; - char *middle_name; - char *mileage; - char *mobile_phone; - char *nickname; - char *office_loc; - char *org_id; - char *other_address; // 0x801c - char *other_city; - char *other_country; - char *other_phone; - char *other_po_box; - char *other_postal_code; - char *other_state; - char *other_street; - char *pager_phone; - char *personal_homepage; - char *pref_name; - char *primary_fax; - char *primary_phone; - char *profession; - char *radio_phone; - int rich_text; // 1 = true, 0 = false - char *spouse_name; - char *suffix; - char *surname; - char *telex; - char *transmittable_display_name; - char *ttytdd_phone; - FILETIME *wedding_anniversary; - char *work_address_street; // 0x8045 - char *work_address_city; // 0x8046 - char *work_address_state; // 0x8047 - char *work_address_postalcode; // 0x8048 - char *work_address_country; // 0x8049 - char *work_address_postofficebox; // 0x804a + pst_string access_method; + pst_string account_name; + pst_string address1; + pst_string address1a; + pst_string address1_desc; + pst_string address1_transport; + pst_string address2; + pst_string address2a; + pst_string address2_desc; + pst_string address2_transport; + pst_string address3; + pst_string address3a; + pst_string address3_desc; + pst_string address3_transport; + pst_string assistant_name; + pst_string assistant_phone; + pst_string billing_information; + FILETIME *birthday; + pst_string business_address; // 0x801b + pst_string business_city; + pst_string business_country; + pst_string business_fax; + pst_string business_homepage; + pst_string business_phone; + pst_string business_phone2; + pst_string business_po_box; + pst_string business_postal_code; + pst_string business_state; + pst_string business_street; + pst_string callback_phone; + pst_string car_phone; + pst_string company_main_phone; + pst_string company_name; + pst_string computer_name; + pst_string customer_id; + pst_string def_postal_address; + pst_string department; + pst_string display_name_prefix; + pst_string first_name; + pst_string followup; + pst_string free_busy_address; + pst_string ftp_site; + pst_string fullname; + int16_t gender; + pst_string gov_id; + pst_string hobbies; + pst_string home_address; // 0x801a + pst_string home_city; + pst_string home_country; + pst_string home_fax; + pst_string home_phone; + pst_string home_phone2; + pst_string home_po_box; + pst_string home_postal_code; + pst_string home_state; + pst_string home_street; + pst_string initials; + pst_string isdn_phone; + pst_string job_title; + pst_string keyword; + pst_string language; + pst_string location; + int mail_permission; // 1 = true, 0 = false + pst_string manager_name; + pst_string middle_name; + pst_string mileage; + pst_string mobile_phone; + pst_string nickname; + pst_string office_loc; + pst_string common_name; + pst_string org_id; + pst_string other_address; // 0x801c + pst_string other_city; + pst_string other_country; + pst_string other_phone; + pst_string other_po_box; + pst_string other_postal_code; + pst_string other_state; + pst_string other_street; + pst_string pager_phone; + pst_string personal_homepage; + pst_string pref_name; + pst_string primary_fax; + pst_string primary_phone; + pst_string profession; + pst_string radio_phone; + int rich_text; // 1 = true, 0 = false + pst_string spouse_name; + pst_string suffix; + pst_string surname; + pst_string telex; + pst_string transmittable_display_name; + pst_string ttytdd_phone; + FILETIME *wedding_anniversary; + pst_string work_address_street; // 0x8045 + pst_string work_address_city; // 0x8046 + pst_string work_address_state; // 0x8047 + pst_string work_address_postalcode; // 0x8048 + pst_string work_address_country; // 0x8049 + pst_string work_address_postofficebox; // 0x804a } pst_item_contact; typedef struct pst_item_attach { - char *filename1; - char *filename2; - char *mimetype; - char *data; - size_t size; - uint64_t id2_val; - uint64_t id_val; // calculated from id2_val during creation of record - pst_id2_ll *id2_head; // deep copy from child - int32_t method; - int32_t position; - int32_t sequence; + pst_string filename1; + pst_string filename2; + pst_string mimetype; + char *data; + size_t size; + uint64_t id2_val; + uint64_t id_val; // calculated from id2_val during creation of record + pst_id2_ll *id2_head; // deep copy from child + int32_t method; + int32_t position; + int32_t sequence; struct pst_item_attach *next; } pst_item_attach; typedef struct pst_item_extra_field { - char *field_name; - char *value; + char *field_name; + char *value; struct pst_item_extra_field *next; } pst_item_extra_field; typedef struct pst_item_journal { - FILETIME *end; - FILETIME *start; - char *type; + FILETIME *end; + FILETIME *start; + pst_string type; } pst_item_journal; typedef struct pst_item_appointment { - FILETIME *end; - char *location; - int alarm; // 1 = true, 0 = false - FILETIME *reminder; - int32_t alarm_minutes; - char *alarm_filename; - FILETIME *start; - char *timezonestring; - int32_t showas; - int32_t label; - int all_day; // 1 = true, 0 = false - char *recurrence; - int32_t recurrence_type; - FILETIME *recurrence_start; - FILETIME *recurrence_end; + FILETIME *end; + pst_string location; + int alarm; // 1 = true, 0 = false + FILETIME *reminder; + int32_t alarm_minutes; + pst_string alarm_filename; + FILETIME *start; + pst_string timezonestring; + int32_t showas; + int32_t label; + int all_day; // 1 = true, 0 = false + pst_string recurrence; + int32_t recurrence_type; + FILETIME *recurrence_start; + FILETIME *recurrence_end; } pst_item_appointment; @@ -432,14 +426,16 @@ struct pst_item_appointment *appointment; // data referring to a calendar entry int type; char *ascii_type; - char *file_as; - char *comment; - char *body_charset; // null if not specified + pst_string file_as; + pst_string comment; + pst_string body_charset; // null if not specified + pst_string body; // email, journal + pst_string subject; // email, journal int32_t internet_cpid; int32_t message_codepage; int32_t message_size; - char *outlook_version; - char *record_key; // probably 16 bytes long. + pst_string outlook_version; + char *record_key; // probably 16 bytes long. size_t record_key_size; int response_requested; // 1 = true, 0 = false FILETIME *create_date; @@ -589,6 +585,11 @@ void pst_printIDptr(pst_file* pf); void pst_printID2ptr(pst_id2_ll *ptr); +const char* pst_codepage(int cp); +const char* pst_default_charset(pst_item *item); +void pst_convert_utf8_null(pst_item *item, pst_string *str); +void pst_convert_utf8(pst_item *item, pst_string *str); + // switch from maximal packing back to default packing // undo the packing from the beginning of this file diff -r 06aa84023b48 -r cda7c812ec01 src/libstrfunc.c --- a/src/libstrfunc.c Thu Mar 05 08:23:32 2009 -0800 +++ b/src/libstrfunc.c Sun Mar 08 14:35:26 2009 -0700 @@ -63,29 +63,3 @@ }; -void hexdump(char *hbuf, int start, int stop, int ascii) /* {{{ HexDump all or a part of some buffer */ -{ - char c; - int diff,i; - - while (start < stop ) { - diff = stop - start; - if (diff > 16) diff = 16; - - fprintf(stderr, ":%08X ",start); - - for (i = 0; i < diff; i++) { - if( 8 == i ) fprintf( stderr, " " ); - fprintf(stderr, "%02X ",(unsigned char)*(hbuf+start+i)); - } - if (ascii) { - for (i = diff; i < 16; i++) fprintf(stderr, " "); - for (i = 0; i < diff; i++) { - c = *(hbuf+start+i); - fprintf(stderr, "%c", isprint(c) ? c : '.'); - } - } - fprintf(stderr, "\n"); - start += 16; - } -} diff -r 06aa84023b48 -r cda7c812ec01 src/lspst.c --- a/src/lspst.c Thu Mar 05 08:23:32 2009 -0800 +++ b/src/lspst.c Sun Mar 08 14:35:26 2009 -0700 @@ -28,12 +28,13 @@ void create_enter_dir(struct file_ll* f, pst_item *item) { + pst_convert_utf8(item, &item->file_as); f->email_count = 0; f->skip_count = 0; f->type = item->type; f->stored_count = (item->folder) ? item->folder->email_count : 0; - f->dname = (char*) xmalloc(strlen(item->file_as)+1); - strcpy(f->dname, item->file_as); + f->dname = (char*) xmalloc(strlen(item->file_as.str)+1); + strcpy(f->dname, item->file_as.str); } @@ -70,7 +71,8 @@ if (item->folder && d_ptr->child) { // if this is a folder, we want to recurse into it - printf("Folder \"%s\"\n", item->file_as); + pst_convert_utf8(item, &item->file_as); + printf("Folder \"%s\"\n", item->file_as.str); process(item, d_ptr->child); } else if (item->contact && (item->type == PST_TYPE_CONTACT)) { @@ -79,8 +81,8 @@ DEBUG_MAIN(("main: I have a contact, but the folder isn't a contacts folder. Processing anyway\n")); } printf("Contact"); - if (item->contact->fullname) - printf("\t%s", pst_rfc2426_escape(item->contact->fullname)); + if (item->contact->fullname.str) + printf("\t%s", pst_rfc2426_escape(item->contact->fullname.str)); printf("\n"); } else if (item->email && (item->type == PST_TYPE_NOTE || item->type == PST_TYPE_REPORT || item->type == PST_TYPE_OTHER)) { @@ -89,10 +91,10 @@ DEBUG_MAIN(("main: I have an email, but the folder isn't an email folder. Processing anyway\n")); } printf("Email"); - if (item->email->outlook_sender_name) - printf("\tFrom: %s", item->email->outlook_sender_name); - if (item->email->subject && item->email->subject->subj) - printf("\tSubject: %s", item->email->subject->subj); + if (item->email->outlook_sender_name.str) + printf("\tFrom: %s", item->email->outlook_sender_name.str); + if (item->subject.str) + printf("\tSubject: %s", item->subject.str); printf("\n"); } else if (item->journal && (item->type == PST_TYPE_JOURNAL)) { @@ -100,8 +102,8 @@ if (ff.type != PST_TYPE_JOURNAL) { DEBUG_MAIN(("main: I have a journal entry, but folder isn't specified as a journal type. Processing...\n")); } - if (item->email && item->email->subject && item->email->subject->subj) - printf("Journal\t%s\n", pst_rfc2426_escape(item->email->subject->subj)); + if (item->subject.str) + printf("Journal\t%s\n", pst_rfc2426_escape(item->subject.str)); } else if (item->appointment && (item->type == PST_TYPE_APPOINTMENT)) { // Process Calendar Appointment item @@ -110,8 +112,8 @@ DEBUG_MAIN(("main: I have an appointment, but folder isn't specified as an appointment type. Processing...\n")); } printf("Appointment"); - if (item->email && item->email->subject) - printf("\tSUMMARY: %s", pst_rfc2426_escape(item->email->subject->subj)); + if (item->subject.str) + printf("\tSUMMARY: %s", pst_rfc2426_escape(item->subject.str)); if (item->appointment->start) printf("\tSTART: %s", pst_rfc2445_datetime_format(item->appointment->start)); if (item->appointment->end) @@ -222,7 +224,7 @@ } // default the file_as to the same as the main filename if it doesn't exist - if (!item->file_as) { + if (!item->file_as.str) { if (!(temp = strrchr(argv[1], '/'))) if (!(temp = strrchr(argv[1], '\\'))) temp = argv[1]; @@ -230,10 +232,11 @@ temp++; // get past the "\\" else temp++; // get past the "/" - item->file_as = (char*)xmalloc(strlen(temp)+1); - strcpy(item->file_as, temp); + item->file_as.str = (char*)xmalloc(strlen(temp)+1); + strcpy(item->file_as.str, temp); + item->file_as.is_utf8 = 1; } - fprintf(stderr, "item->file_as = '%s'.\n", item->file_as); + WARN(("item->file_as = '%s'.\n", item->file_as.str)); d_ptr = pst_getTopOfFolders(&pstfile, item); if (!d_ptr) DIE(("Top of folders record not found. Cannot continue\n")); @@ -262,48 +265,3 @@ } -void debug_print(char *fmt, ...) { - // shamlessly stolen from minprintf() in K&R pg. 156 - va_list ap; - char *p, *sval; - void *pval; - int ival; - double dval; - FILE *fp = stderr; - - va_start(ap, fmt); - for(p = fmt; *p; p++) { - if (*p != '%') { - fputc(*p, fp); - continue; - } - switch (tolower(*++p)) { - case 'd': case 'i': - ival = va_arg(ap, int); - fprintf(fp, "%d", ival); - break; - case 'f': - dval = va_arg(ap, double); - fprintf(fp, "%f", dval); - break; - case 's': - for (sval = va_arg(ap, char *); *sval; ++sval) - fputc(*sval, fp); - break; - case 'p': - pval = va_arg(ap, void *); - fprintf(fp, "%p", pval); - break; - case 'x': - ival = va_arg(ap, int); - fprintf(fp, "%#010x", ival); - break; - default: - fputc(*p, fp); - break; - } - } - va_end(ap); -} - - diff -r 06aa84023b48 -r cda7c812ec01 src/pst2dii.cpp.in --- a/src/pst2dii.cpp.in Thu Mar 05 08:23:32 2009 -0800 +++ b/src/pst2dii.cpp.in Sun Mar 08 14:35:26 2009 -0700 @@ -175,8 +175,8 @@ // 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; + char *attach_filename = (current_attach->filename2.str) ? current_attach->filename2.str + : current_attach->filename1.str; DEBUG_ENT("write_separate_attachment"); check_filename(fname); const char* f_name = fname.c_str(); @@ -445,17 +445,17 @@ { DEBUG_ENT("write_normal_email"); char *soh = NULL; // real start of headers. - if (item->email->header) { + if (item->email->header.str) { // 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); - char *temp = strstr(item->email->header, "\n\n"); + removeCR(item->email->header.str); + char *temp = strstr(item->email->header.str, "\n\n"); if (temp) { DEBUG_EMAIL(("Found body text in header\n")); temp[1] = '\0'; // stop after first \n } - soh = skip_header_prologue(item->email->header); + soh = skip_header_prologue(item->email->header.str); } char folder_line[LINE_SIZE]; @@ -471,13 +471,13 @@ string myto = extract_header(soh, "To"); string mycc = extract_header(soh, "Cc"); string mybcc = extract_header(soh, "Bcc"); - if (myfrom.empty()) write_simple("FROM", item->email->outlook_sender_name, item->email->sender_address); + if (myfrom.empty()) write_simple("FROM", item->email->outlook_sender_name.str, item->email->sender_address.str); else write_simple("FROM", myfrom); - if (myto.empty()) write_simple("TO", item->email->sentto_address, item->email->recip_address); + if (myto.empty()) write_simple("TO", item->email->sentto_address.str, item->email->recip_address.str); else write_simple("TO", myto); - if (mycc.empty()) write_simple("CC", item->email->cc_address); + if (mycc.empty()) write_simple("CC", item->email->cc_address.str); else write_simple("CC", mycc); - if (mybcc.empty()) write_simple("BCC", item->email->bcc_address); + if (mybcc.empty()) write_simple("BCC", item->email->bcc_address.str); else write_simple("BCC", mybcc); if (item->email->sent_date) { time_t t = fileTimeToUnixTime(item->email->sent_date, NULL); @@ -495,10 +495,10 @@ strftime(c_time, C_TIME_SIZE, "%T+0000", gmtime(&t)); write_simple("TIMERCVD", c_time); } - if (item->email->subject) { - write_simple("SUBJECT", item->email->subject->subj); + if (item->subject.str) { + write_simple("SUBJECT", item->subject.str); } - write_simple("MSGID", item->email->messageid); + write_simple("MSGID", item->email->messageid.str); if (item->email->flag) { write_simple("READ", (item->email->flag & 1) ? "Y" : "N"); } @@ -506,8 +506,8 @@ DEBUG_EMAIL(("About to print Header\n")); fprintf(dii_file, "@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 && item->subject.str) { + DEBUG_EMAIL(("item->subject = %s\n", item->subject.str)); } if (soh) { @@ -521,23 +521,23 @@ } else { //make up our own headers - const char *temp = item->email->outlook_sender; + const char *temp = item->email->outlook_sender.str; if (!temp) temp = ""; - snprintf(line, sizeof(line), "From: \"%s\" <%s>\n", item->email->outlook_sender_name, temp); + snprintf(line, sizeof(line), "From: \"%s\" <%s>\n", item->email->outlook_sender_name.str, temp); print_pdf(line); - if (item->email->subject) { - snprintf(line, sizeof(line), "Subject: %s\n", item->email->subject->subj); + if (item->subject.str) { + snprintf(line, sizeof(line), "Subject: %s\n", item->subject.str); } else { snprintf(line, sizeof(line), "Subject: \n"); } print_pdf(line); - snprintf(line, sizeof(line), "To: %s\n", item->email->sentto_address); + snprintf(line, sizeof(line), "To: %s\n", item->email->sentto_address.str); print_pdf(line); - if (item->email->cc_address) { - snprintf(line, sizeof(line), "Cc: %s\n", item->email->cc_address); + if (item->email->cc_address.str) { + snprintf(line, sizeof(line), "Cc: %s\n", item->email->cc_address.str); print_pdf(line); } @@ -555,12 +555,12 @@ DEBUG_EMAIL(("About to print Body\n")); fprintf(dii_file, "@EMAIL-BODY\n"); - if (item->email->body) { - removeCR(item->email->body); - print_pdf(item->email->body); - } else if (item->email->htmlbody) { - removeCR(item->email->htmlbody); - print_pdf(item->email->htmlbody); + if (item->body.str) { + removeCR(item->body.str); + print_pdf(item->body.str); + } else if (item->email->htmlbody.str) { + removeCR(item->email->htmlbody.str); + print_pdf(item->email->htmlbody.str); } else if (item->email->encrypted_body || item->email->encrypted_htmlbody) { char ln[LINE_SIZE]; snprintf(ln, sizeof(ln), "%s", "The body of this email is encrypted. This isn't supported yet, but the body is now an attachment\n"); @@ -591,7 +591,7 @@ f.skip_count = 0; f.type = item->type; f.stored_count = (item->folder) ? item->folder->email_count : 0; - f.name = ((parent) ? parent->name + "/" : "") + string(item->file_as); + f.name = ((parent) ? parent->name + "/" : "") + string(item->file_as.str); } diff -r 06aa84023b48 -r cda7c812ec01 src/pst2ldif.cpp --- a/src/pst2ldif.cpp Thu Mar 05 08:23:32 2009 -0800 +++ b/src/pst2ldif.cpp Sun Mar 08 14:35:26 2009 -0700 @@ -24,19 +24,19 @@ void version(void); char *check_filename(char *fname); void print_ldif_single(const char *attr, const char *value); -void print_ldif_address(const char *attr, int nvalues, char *value, ...); -void print_ldif_dn(const char *attr, const char *value, const char *base); -void print_ldif_multi(const char *dn, const char *value); -void print_ldif_two(const char *attr, const char *value1, const char *value2); +void print_ldif_single(const char *attr, pst_string value); +void print_ldif_address(const char *attr, int nvalues, pst_string value, ...); +void print_ldif_dn(const char *attr, pst_string value, const char *base); +void print_ldif_multi(const char *dn, pst_string value); +void print_ldif_two(const char *attr, pst_string value1, pst_string value2); void print_escaped_dn(const char *value); -void build_cn(char *cn, size_t len, int nvalues, char *value, ...); +void build_cn(char *cn, size_t len, int nvalues, pst_string value, ...); char *prog_name; pst_file pstfile; bool old_schema = false; char *ldap_base = NULL; // 'o=some.domain.tld,c=US' int ldif_extra_line_count = 0; -iconv_t cd = 0; // Character set conversion descriptor vector ldap_class; // 'newPerson' or 'inetOrgPerson' vector ldif_extra_line; // 'o: myorg' @@ -108,21 +108,64 @@ static void process(pst_desc_ll *d_ptr); static void process(pst_desc_ll *d_ptr) { + DEBUG_ENT("process"); pst_item *item = NULL; while (d_ptr) { if (d_ptr->desc) { item = pst_parse_item(&pstfile, d_ptr, NULL); DEBUG_INFO(("item pointer is %p\n", item)); if (item) { - if (item->folder && d_ptr->child && strcasecmp(item->file_as, "Deleted Items")) { + if (item->folder && d_ptr->child && item->file_as.str && strcasecmp(item->file_as.str, "Deleted Items")) { //if this is a non-empty folder other than deleted items, we want to recurse into it - fprintf(stderr, "entering folder %s\n", item->file_as); + fprintf(stderr, "entering folder %s\n", item->file_as.str); process(d_ptr->child); } else if (item->contact && (item->type == PST_TYPE_CONTACT)) { // deal with a contact char cn[1000]; + // convert everything to utf8 + pst_convert_utf8_null(item, &item->contact->display_name_prefix); + pst_convert_utf8_null(item, &item->contact->first_name); + pst_convert_utf8_null(item, &item->contact->surname); + pst_convert_utf8_null(item, &item->contact->suffix); + pst_convert_utf8_null(item, &item->contact->company_name); + pst_convert_utf8_null(item, &item->contact->job_title); + pst_convert_utf8_null(item, &item->contact->address1); + pst_convert_utf8_null(item, &item->contact->address2); + pst_convert_utf8_null(item, &item->contact->address3); + pst_convert_utf8_null(item, &item->contact->address1a); + pst_convert_utf8_null(item, &item->contact->address2a); + pst_convert_utf8_null(item, &item->contact->address3a); + pst_convert_utf8_null(item, &item->contact->business_address); + pst_convert_utf8_null(item, &item->contact->business_po_box); + pst_convert_utf8_null(item, &item->contact->business_street); + pst_convert_utf8_null(item, &item->contact->business_city); + pst_convert_utf8_null(item, &item->contact->business_state); + pst_convert_utf8_null(item, &item->contact->business_postal_code); + pst_convert_utf8_null(item, &item->contact->home_address); + pst_convert_utf8_null(item, &item->contact->home_po_box); + pst_convert_utf8_null(item, &item->contact->home_street); + pst_convert_utf8_null(item, &item->contact->home_city); + pst_convert_utf8_null(item, &item->contact->home_state); + pst_convert_utf8_null(item, &item->contact->home_postal_code); + pst_convert_utf8_null(item, &item->contact->other_address); + pst_convert_utf8_null(item, &item->contact->other_po_box); + pst_convert_utf8_null(item, &item->contact->other_street); + pst_convert_utf8_null(item, &item->contact->other_city); + pst_convert_utf8_null(item, &item->contact->other_state); + pst_convert_utf8_null(item, &item->contact->other_postal_code); + pst_convert_utf8_null(item, &item->contact->business_fax); + pst_convert_utf8_null(item, &item->contact->home_fax); + pst_convert_utf8_null(item, &item->contact->business_phone); + pst_convert_utf8_null(item, &item->contact->home_phone); + pst_convert_utf8_null(item, &item->contact->car_phone); + pst_convert_utf8_null(item, &item->contact->mobile_phone); + pst_convert_utf8_null(item, &item->contact->other_phone); + pst_convert_utf8_null(item, &item->contact->business_homepage); + pst_convert_utf8_null(item, &item->contact->personal_homepage); + pst_convert_utf8_null(item, &item->comment); + build_cn(cn, sizeof(cn), 4, item->contact->display_name_prefix, item->contact->first_name, @@ -130,93 +173,94 @@ item->contact->suffix); if (cn[0] != 0) { // have a valid cn - const char *ucn = unique_string(cn); + pst_string ucn; + ucn.str = (char*)unique_string(cn); print_ldif_dn("dn", ucn, ldap_base); print_ldif_single("cn", ucn); - if (item->contact->first_name) { + if (item->contact->first_name.str) { print_ldif_two("givenName", item->contact->display_name_prefix, item->contact->first_name); } - if (item->contact->surname) { + if (item->contact->surname.str) { print_ldif_two("sn", item->contact->surname, item->contact->suffix); } - else if (item->contact->company_name) { + else if (item->contact->company_name.str) { print_ldif_single("sn", item->contact->company_name); } else print_ldif_single("sn", ucn); // use cn as sn if we cannot find something better if (old_schema) { - if (item->contact->job_title) + if (item->contact->job_title.str) print_ldif_single("personalTitle", item->contact->job_title); - if (item->contact->company_name) + if (item->contact->company_name.str) print_ldif_single("company", item->contact->company_name); } else { // new schema - if (item->contact->job_title) + if (item->contact->job_title.str) print_ldif_single("title", item->contact->job_title); - if (item->contact->company_name) + if (item->contact->company_name.str) print_ldif_single("o", item->contact->company_name); } - if (item->contact->address1 && *item->contact->address1) + if (item->contact->address1.str && *item->contact->address1.str) print_ldif_single("mail", item->contact->address1); - if (item->contact->address2 && *item->contact->address2) + if (item->contact->address2.str && *item->contact->address2.str) print_ldif_single("mail", item->contact->address2); - if (item->contact->address3 && *item->contact->address3) + if (item->contact->address3.str && *item->contact->address3.str) print_ldif_single("mail", item->contact->address3); - if (item->contact->address1a && *item->contact->address1a) + if (item->contact->address1a.str && *item->contact->address1a.str) print_ldif_single("mail", item->contact->address1a); - if (item->contact->address2a && *item->contact->address2a) + if (item->contact->address2a.str && *item->contact->address2a.str) print_ldif_single("mail", item->contact->address2a); - if (item->contact->address3a && *item->contact->address3a) + if (item->contact->address3a.str && *item->contact->address3a.str) print_ldif_single("mail", item->contact->address3a); if (old_schema) { - if (item->contact->business_address) { - if (item->contact->business_po_box) + if (item->contact->business_address.str) { + if (item->contact->business_po_box.str) print_ldif_single("postalAddress", item->contact->business_po_box); - if (item->contact->business_street) + if (item->contact->business_street.str) print_ldif_multi("postalAddress", item->contact->business_street); - if (item->contact->business_city) + if (item->contact->business_city.str) print_ldif_single("l", item->contact->business_city); - if (item->contact->business_state) + if (item->contact->business_state.str) print_ldif_single("st", item->contact->business_state); - if (item->contact->business_postal_code) + if (item->contact->business_postal_code.str) print_ldif_single("postalCode", item->contact->business_postal_code); } - else if (item->contact->home_address) { - if (item->contact->home_po_box) + else if (item->contact->home_address.str) { + if (item->contact->home_po_box.str) print_ldif_single("postalAddress", item->contact->home_po_box); - if (item->contact->home_street) + if (item->contact->home_street.str) print_ldif_multi("postalAddress", item->contact->home_street); - if (item->contact->home_city) + if (item->contact->home_city.str) print_ldif_single("l", item->contact->home_city); - if (item->contact->home_state) + if (item->contact->home_state.str) print_ldif_single("st", item->contact->home_state); - if (item->contact->home_postal_code) + if (item->contact->home_postal_code.str) print_ldif_single("postalCode", item->contact->home_postal_code); } - else if (item->contact->other_address) { - if (item->contact->other_po_box) + else if (item->contact->other_address.str) { + if (item->contact->other_po_box.str) print_ldif_single("postalAddress", item->contact->other_po_box); - if (item->contact->other_street) + if (item->contact->other_street.str) print_ldif_multi("postalAddress", item->contact->other_street); - if (item->contact->other_city) + if (item->contact->other_city.str) print_ldif_single("l", item->contact->other_city); - if (item->contact->other_state) + if (item->contact->other_state.str) print_ldif_single("st", item->contact->other_state); - if (item->contact->other_postal_code) + if (item->contact->other_postal_code.str) print_ldif_single("postalCode", item->contact->other_postal_code); } } else { // new schema, with proper RFC4517 postal addresses - if (item->contact->business_address) { + if (item->contact->business_address.str) { print_ldif_address("postalAddress", 6, item->contact->business_po_box, item->contact->business_street, @@ -224,22 +268,22 @@ item->contact->business_state, item->contact->business_postal_code, item->contact->business_country); - if (item->contact->business_city) + if (item->contact->business_city.str) print_ldif_single("l", item->contact->business_city); - if (item->contact->business_state) + if (item->contact->business_state.str) print_ldif_single("st", item->contact->business_state); - if (item->contact->business_postal_code) + if (item->contact->business_postal_code.str) print_ldif_single("postalCode", item->contact->business_postal_code); } - else if (item->contact->home_address) { - if (item->contact->home_city) + else if (item->contact->home_address.str) { + if (item->contact->home_city.str) print_ldif_single("l", item->contact->home_city); - if (item->contact->home_state) + if (item->contact->home_state.str) print_ldif_single("st", item->contact->home_state); - if (item->contact->home_postal_code) + if (item->contact->home_postal_code.str) print_ldif_single("postalCode", item->contact->home_postal_code); } - else if (item->contact->other_address) { + else if (item->contact->other_address.str) { print_ldif_address("postalAddress", 6, item->contact->other_po_box, item->contact->other_street, @@ -247,14 +291,14 @@ item->contact->other_state, item->contact->other_postal_code, item->contact->other_country); - if (item->contact->other_city) + if (item->contact->other_city.str) print_ldif_single("l", item->contact->other_city); - if (item->contact->other_state) + if (item->contact->other_state.str) print_ldif_single("st", item->contact->other_state); - if (item->contact->other_postal_code) + if (item->contact->other_postal_code.str) print_ldif_single("postalCode", item->contact->other_postal_code); } - if (item->contact->home_address) { + if (item->contact->home_address.str) { print_ldif_address("homePostalAddress", 6, item->contact->home_po_box, item->contact->home_street, @@ -265,31 +309,31 @@ } } - if (item->contact->business_fax) + if (item->contact->business_fax.str) print_ldif_single("facsimileTelephoneNumber", item->contact->business_fax); - else if (item->contact->home_fax) + else if (item->contact->home_fax.str) print_ldif_single("facsimileTelephoneNumber", item->contact->home_fax); - if (item->contact->business_phone) + if (item->contact->business_phone.str) print_ldif_single("telephoneNumber", item->contact->business_phone); - if (item->contact->home_phone) + if (item->contact->home_phone.str) print_ldif_single("homePhone", item->contact->home_phone); - if (item->contact->car_phone) + if (item->contact->car_phone.str) print_ldif_single("mobile", item->contact->car_phone); - else if (item->contact->mobile_phone) + else if (item->contact->mobile_phone.str) print_ldif_single("mobile", item->contact->mobile_phone); - else if (item->contact->other_phone) + else if (item->contact->other_phone.str) print_ldif_single("mobile", item->contact->other_phone); if (!old_schema) { - if (item->contact->business_homepage) + if (item->contact->business_homepage.str) print_ldif_single("labeledURI", item->contact->business_homepage); - if (item->contact->personal_homepage) + if (item->contact->personal_homepage.str) print_ldif_single("labeledURI", item->contact->personal_homepage); } - if (item->comment) + if (item->comment.str) print_ldif_single("description", item->comment); for (vector::size_type i=0; inext; } + DEBUG_RET(); +} + + +void print_ldif_single(const char *attr, pst_string value) +{ + print_ldif_single(attr, value.str); } @@ -315,7 +366,6 @@ { size_t len; bool is_safe_string = true; - bool needs_code_conversion = false; bool space_flag = false; // Strip leading spaces @@ -341,7 +391,6 @@ } else { if ((ch & 0x80) == 0x80) { - needs_code_conversion = true; is_safe_string = false; } if (space_flag) { @@ -354,37 +403,20 @@ *p = 0; if (is_safe_string) { printf("%s: %s\n", attr, &buffer[0]); - return; } - - if (needs_code_conversion && cd != 0) { - size_t inlen = p - &buffer[0]; - size_t utf8_len = 2 * inlen + 1; - vector utf8_buffer(utf8_len); - char *utf8_p = &utf8_buffer[0]; - - iconv(cd, NULL, NULL, NULL, NULL); - p = &buffer[0]; - int ret = iconv(cd, (ICONV_CONST char**)&p, &inlen, &utf8_p, &utf8_len); - - if (ret >= 0) { - *utf8_p = 0; - p = base64_encode(&utf8_buffer[0], utf8_p - &utf8_buffer[0]); - } - else - p = base64_encode(&buffer[0], buffer.size()); + else { + p = base64_encode(&buffer[0], buffer.size()); + printf("%s:: %s\n", attr, p); + free(p); } - else - p = base64_encode(&buffer[0], buffer.size()); - printf("%s:: %s\n", attr, p); - free(p); } // Combines values representing address lines into an address,i // lines separated with "$" as per PostalAddress syntax in RFC4517 -void print_ldif_address(const char *attr, int nvalues, char *value, ...) +void print_ldif_address(const char *attr, int nvalues, pst_string value, ...) { + DEBUG_ENT("print_ldif_address"); bool space_flag = false; bool newline_flag = false; char *address = NULL; // Buffer where address is built up @@ -393,26 +425,26 @@ va_list ap; va_start(ap, value); + while (!value.str) { + nvalues--; + if (nvalues == 0) { // Nothing at all to do! + va_end(ap); + DEBUG_RET(); + return; + } + value = va_arg(ap, pst_string); + } - while (!value) { - nvalues--; - if (nvalues == 0) { // Nothing at all to do! - va_end(ap); - return; - } - value = va_arg(ap, char *); - } for (;;) { - char ch = *value++; + char ch = *(value.str)++; - if (ch == 0 || ch == '\n') { + if (ch == 0) { do { - value = NULL; nvalues--; if (nvalues == 0) break; - value = va_arg(ap, char *); - } while (!value); - if (!value) break; + value = va_arg(ap, pst_string); + } while (!value.str); + if (!nvalues || !value.str) break; space_flag = true; newline_flag = true; } @@ -449,46 +481,48 @@ address[i] = 0; print_ldif_single(attr, address); free(address); + DEBUG_RET(); } -void print_ldif_multi(const char *dn, const char *value) +void print_ldif_multi(const char *dn, pst_string value) { - const char *n; - while ((n = strchr(value, '\n'))) { - print_ldif_single(dn, value); - value = n + 1; + char *n; + char *valuestr = value.str; + while ((n = strchr(valuestr, '\n'))) { + print_ldif_single(dn, valuestr); + valuestr = n + 1; } - print_ldif_single(dn, value); + print_ldif_single(dn, valuestr); } -void print_ldif_two(const char *attr, const char *value1, const char *value2) +void print_ldif_two(const char *attr, pst_string value1, pst_string value2) { size_t len1, len2; - if (value1 && *value1) - len1 = strlen(value1); + if (value1.str && *value1.str) + len1 = strlen(value1.str); else { print_ldif_single(attr, value2); return; } - if (value2 && *value2) - len2 = strlen(value2); + if (value2.str && *value2.str) + len2 = strlen(value2.str); else { print_ldif_single(attr, value1); return; } vector value(len1 + len2 + 2); - memcpy(&value[0], value1, len1); + memcpy(&value[0], value1.str, len1); value[len1] = ' '; - memcpy(&value[0] + len1 + 1, value2, len2 + 1); + memcpy(&value[0] + len1 + 1, value2.str, len2 + 1); print_ldif_single(attr, &value[0]); } -void build_cn(char *cn, size_t len, int nvalues, char *value, ...) +void build_cn(char *cn, size_t len, int nvalues, pst_string value, ...) { bool space_flag = false; size_t i = 0; @@ -496,26 +530,25 @@ va_start(ap, value); - while (!value) { + while (!value.str) { nvalues--; if (nvalues == 0) { cn[0] = 0; // Just a terminating NUL va_end(ap); return; } - value = va_arg(ap, char *); + value = va_arg(ap, pst_string); } for (;;) { - char ch = *value++; + char ch = *(value.str)++; if (ch == 0 || ch == '\n') { do { - value = NULL; nvalues--; if (nvalues == 0) break; - value = va_arg(ap, char *); - } while (!value); - if (!value) break; + value = va_arg(ap, pst_string); + } while (!value.str); + if (!nvalues || !value.str) break; space_flag = true; } else if (ch == '\r') @@ -549,7 +582,7 @@ prog_name = argv[0]; pst_item *item = NULL; - while ((c = getopt(argc, argv, "b:c:C:d:l:oVh"))!= -1) { + while ((c = getopt(argc, argv, "b:c:d:l:oVh"))!= -1) { switch (c) { case 'b': ldap_base = optarg; @@ -557,14 +590,6 @@ case 'c': ldap_class.push_back(string(optarg)); break; - case 'C': - cd = iconv_open("UTF-8", optarg); - if (cd == (iconv_t)(-1)) { - fprintf(stderr, "I don't know character set \"%s\"!\n\n", optarg); - fprintf(stderr, "Type: \"iconv --list\" to get list of known character sets\n"); - return 1; - } - break; case 'd': d_log = optarg; break; @@ -645,8 +670,6 @@ pst_close(&pstfile); DEBUG_RET(); free_strings(all_strings); - if (cd) iconv_close(cd); - return 0; } @@ -656,7 +679,6 @@ printf("Usage: %s [OPTIONS] {PST FILENAME}\n", prog_name); printf("OPTIONS:\n"); printf("\t-V\t- Version. Display program version\n"); - printf("\t-C charset\t- assumed character set of non-ASCII characters\n"); printf("\t-b ldapbase\t- set the LDAP base value\n"); printf("\t-c class\t- set the class of the LDAP objects (may contain more than one)\n"); printf("\t-d \t- Debug to file. This is a binary log. Use readpstlog to print it\n"); @@ -695,14 +717,15 @@ // This function escapes Distinguished Names (as per RFC4514) -void print_ldif_dn(const char *attr, const char *value, const char *base) +void print_ldif_dn(const char *attr, pst_string value, const char *base) { printf("dn: cn="); + const char *valuestr = value.str; // remove leading spaces (RFC says escape them) - while (*value == ' ') - value++; + while (*valuestr == ' ') + valuestr++; - print_escaped_dn(value); + print_escaped_dn(valuestr); if (base && base[0]) { printf(", %s", base); } @@ -714,34 +737,6 @@ void print_escaped_dn(const char *value) { char ch; - bool needs_code_conversion = false; - char *utf8_buffer = NULL; - - // First do a quick scan to see if any code conversion is required - if (cd) { - const char *p = value; - while (*p) { - if (*p++ & 0x80) { - needs_code_conversion = true; - break; - } - } - } - - if (needs_code_conversion) { - size_t inlen = strlen(value); - size_t utf8_len = 2 * inlen + 1; - char *p = (char *)value; - char *utf8_p = utf8_buffer; - - utf8_buffer = (char *)malloc(utf8_len); - utf8_p = utf8_buffer; - iconv(cd, NULL, NULL, NULL, NULL); - if (iconv(cd, (ICONV_CONST char**)&p, &inlen, &utf8_p, &utf8_len) >= 0) { - *utf8_p = 0; - value = utf8_buffer; - } - } // escape initial '#' and space if (*value == '#' || *value == ' ') @@ -765,6 +760,5 @@ putchar(ch); } } - if (utf8_buffer) free((void *)utf8_buffer); return; } diff -r 06aa84023b48 -r cda7c812ec01 src/readpst.c --- a/src/readpst.c Thu Mar 05 08:23:32 2009 -0800 +++ b/src/readpst.c Sun Mar 08 14:35:26 2009 -0700 @@ -51,11 +51,11 @@ int test_base64(char *body); void find_html_charset(char *html, char *charset, size_t charsetlen); void find_rfc822_headers(char** extra_mime_headers); -void write_body_part(FILE* f_output, char *body, int32_t body_was_unicode, char *mime, char *charset, char *boundary, pst_file* pst); +void write_body_part(FILE* f_output, pst_string *body, char *mime, char *charset, 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, int save_rtf, char** extra_mime_headers); -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); +void write_vcard(FILE* f_output, pst_item *item, pst_item_contact* contact, char comment[]); +void write_appointment(FILE* f_output, pst_item *item, pst_item_appointment* appointment, + FILETIME* create_date, FILETIME* modify_date); void create_enter_dir(struct file_ll* f, pst_item *item); void close_enter_dir(struct file_ll *f); @@ -140,13 +140,13 @@ item = pst_parse_item(&pstfile, d_ptr, NULL); DEBUG_MAIN(("main: About to process item\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 && item->subject.str) { + DEBUG_EMAIL(("item->subject = %s\n", item->subject.str)); } if (item) { - if (item->folder && d_ptr->child && (deleted_mode == DMODE_INCLUDE || strcasecmp(item->file_as, "Deleted Items"))) { + if (item->folder && d_ptr->child && item->file_as.str && (deleted_mode == DMODE_INCLUDE || strcasecmp(item->file_as.str, "Deleted Items"))) { //if this is a non-empty folder other than deleted items, we want to recurse into it - if (output_mode != OUTPUT_QUIET) printf("Processing Folder \"%s\"\n", item->file_as); + if (output_mode != OUTPUT_QUIET) printf("Processing Folder \"%s\"\n", item->file_as.str); process(item, d_ptr->child); } else if (item->contact && (item->type == PST_TYPE_CONTACT)) { @@ -159,10 +159,15 @@ if (ff.type != PST_TYPE_CONTACT) { DEBUG_MAIN(("main: I have a contact, but the folder isn't a contacts folder. Processing anyway\n")); } - if (contact_mode == CMODE_VCARD) - write_vcard(ff.output, item->contact, item->comment); - else - fprintf(ff.output, "%s <%s>\n", item->contact->fullname, item->contact->address1); + if (contact_mode == CMODE_VCARD) { + pst_convert_utf8_null(item, &item->comment); + write_vcard(ff.output, item, item->contact, item->comment.str); + } + else { + pst_convert_utf8(item, &item->contact->fullname); + pst_convert_utf8(item, &item->contact->address1); + fprintf(ff.output, "%s <%s>\n", item->contact->fullname.str, item->contact->address1.str); + } } else if (item->email && (item->type == PST_TYPE_NOTE || item->type == PST_TYPE_REPORT || item->type == PST_TYPE_OTHER)) { char *extra_mime_headers = NULL; @@ -183,10 +188,14 @@ DEBUG_MAIN(("main: I have a journal entry, but the folder isn't a journal folder. Processing anyway\n")); } fprintf(ff.output, "BEGIN:VJOURNAL\n"); - if (item->email && item->email->subject && item->email->subject->subj) - fprintf(ff.output, "SUMMARY:%s\n", pst_rfc2426_escape(item->email->subject->subj)); - if (item->email && item->email->body) - fprintf(ff.output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->email->body)); + if (item->subject.str) { + pst_convert_utf8(item, &item->subject); + fprintf(ff.output, "SUMMARY:%s\n", pst_rfc2426_escape(item->subject.str)); + } + if (item->body.str) { + pst_convert_utf8(item, &item->body); + fprintf(ff.output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->body.str)); + } if (item->journal->start) fprintf(ff.output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(item->journal->start)); fprintf(ff.output, "END:VJOURNAL\n\n"); @@ -199,7 +208,7 @@ if (ff.type != PST_TYPE_APPOINTMENT) { DEBUG_MAIN(("main: I have an appointment, but folder isn't specified as an appointment type. Processing...\n")); } - write_appointment(ff.output, item->appointment, item->email, item->create_date, item->modify_date); + write_appointment(ff.output, item, item->appointment, item->create_date, item->modify_date); } else if (item->message_store) { // there should only be one message_store, and we have already done it @@ -209,7 +218,7 @@ // these all seem to be things that MS agrees are not included in the item count //ff.skip_count++; DEBUG_MAIN(("main: Unknown item type %i (%s) name (%s)\n", - item->type, item->ascii_type, item->file_as)); + item->type, item->ascii_type, item->file_as.str)); } pst_freeItem(item); } else { @@ -324,17 +333,17 @@ char buf[1024]; size_t l = 0; if (NULL == (fp = fopen(fname, "rb"))) { - fprintf(stderr, "Couldn't open file %s\n", fname ); + WARN(("Couldn't open file %s\n", fname)); DEBUG_RET(); return 1; } while (0 != (l = fread(buf, 1, 1024, fp))) { if (0 != pst_decrypt(0, buf, l, PST_COMP_ENCRYPT)) - fprintf(stderr, "pst_decrypt() failed (I'll try to continue)\n"); + WARN(("pst_decrypt() failed (I'll try to continue)\n")); if (l != pst_fwrite(buf, 1, l, stdout)) { - fprintf(stderr, "Couldn't output to stdout?\n"); + WARN(("Couldn't output to stdout?\n")); DEBUG_RET(); return 1; } @@ -367,7 +376,7 @@ } // default the file_as to the same as the main filename if it doesn't exist - if (!item->file_as) { + if (!item->file_as.str) { if (!(temp = strrchr(fname, '/'))) if (!(temp = strrchr(fname, '\\'))) temp = fname; @@ -375,11 +384,12 @@ temp++; // get past the "\\" else temp++; // get past the "/" - item->file_as = (char*)xmalloc(strlen(temp)+1); - strcpy(item->file_as, temp); - DEBUG_MAIN(("file_as was blank, so am using %s\n", item->file_as)); + item->file_as.str = (char*)xmalloc(strlen(temp)+1); + strcpy(item->file_as.str, temp); + item->file_as.is_utf8 = 1; + DEBUG_MAIN(("file_as was blank, so am using %s\n", item->file_as.str)); } - DEBUG_MAIN(("main: Root Folder Name: %s\n", item->file_as)); + DEBUG_MAIN(("main: Root Folder Name: %s\n", item->file_as.str)); d_ptr = pst_getTopOfFolders(&pstfile, item); if (!d_ptr) { @@ -398,7 +408,6 @@ void write_email_body(FILE *f, char *body) { char *n = body; - // DEBUG_MAIN(("write_email_body(): \"%s\"\n", body)); DEBUG_ENT("write_email_body"); while (n) { if (strncmp(body, "From ", 5) == 0) @@ -700,8 +709,8 @@ // If there is a long filename (filename2) use that, otherwise // use the 8.3 filename (filename1) - char *attach_filename = (attach->filename2) ? attach->filename2 - : attach->filename1; + char *attach_filename = (attach->filename2.str) ? attach->filename2.str + : attach->filename1.str; DEBUG_ENT("write_separate_attachment"); check_filename(f_name); @@ -744,7 +753,7 @@ pst_index_ll *ptr; DEBUG_ENT("write_embedded_message"); fprintf(f_output, "\n--%s\n", boundary); - fprintf(f_output, "Content-Type: %s\n\n", attach->mimetype); + fprintf(f_output, "Content-Type: %s\n\n", attach->mimetype.str); ptr = pst_getID(pf, attach->id_val); pst_desc_ll d_ptr; @@ -792,16 +801,16 @@ } fprintf(f_output, "\n--%s\n", boundary); - if (!attach->mimetype) { + if (!attach->mimetype.str) { fprintf(f_output, "Content-Type: %s\n", MIME_TYPE_DEFAULT); } else { - fprintf(f_output, "Content-Type: %s\n", attach->mimetype); + fprintf(f_output, "Content-Type: %s\n", attach->mimetype.str); } fprintf(f_output, "Content-Transfer-Encoding: base64\n"); // If there is a long filename (filename2) use that, otherwise // use the 8.3 filename (filename1) - attach_filename = (attach->filename2) ? attach->filename2 : attach->filename1; + attach_filename = (attach->filename2.str) ? attach->filename2.str : attach->filename1.str; if (!attach_filename) { fprintf(f_output, "Content-Disposition: inline\n\n"); } else { @@ -986,18 +995,17 @@ } -void write_body_part(FILE* f_output, char *body, int32_t body_was_unicode, char *mime, char *charset, char *boundary, pst_file* pst) +void write_body_part(FILE* f_output, pst_string *body, char *mime, char *charset, char *boundary, pst_file* pst) { - char *needfree = NULL; DEBUG_ENT("write_body_part"); - if (body_was_unicode && (strcasecmp("utf-8", charset))) { + if (body->is_utf8 && (strcasecmp("utf-8", charset))) { // try to convert to the specified charset since the target // is not utf-8, and the data came from a unicode (utf16) field // and is now in utf-8. size_t rc; DEBUG_EMAIL(("Convert %s utf-8 to %s\n", mime, charset)); vbuf *newer = vballoc(2); - rc = vb_utf8to8bit(newer, body, strlen(body) + 1, charset); + rc = vb_utf8to8bit(newer, body->str, strlen(body->str) + 1, charset); if (rc == (size_t)-1) { // unable to convert, change the charset to utf8 free(newer->b); @@ -1005,18 +1013,19 @@ charset = "utf-8"; } else { - needfree = body = newer->b; + free(body->str); + body->str = newer->b; } free(newer); } - removeCR(body); - int base64 = test_base64(body); + removeCR(body->str); + int base64 = test_base64(body->str); fprintf(f_output, "\n--%s\n", boundary); fprintf(f_output, "Content-Type: %s; charset=\"%s\"\n", mime, charset); if (base64) fprintf(f_output, "Content-Transfer-Encoding: base64\n"); fprintf(f_output, "\n"); if (base64) { - char *enc = base64_encode(body, strlen(body)); + char *enc = base64_encode(body->str, strlen(body->str)); if (enc) { write_email_body(f_output, enc); fprintf(f_output, "\n"); @@ -1024,46 +1033,12 @@ } } else { - write_email_body(f_output, body); + write_email_body(f_output, body->str); } - if (needfree) free(needfree); DEBUG_RET(); } -const char* codepage(int cp); -const char* codepage(int cp) { - static char buffer[20]; - switch (cp) { - case 932 : return "iso-2022-jp"; - case 936 : return "gb2313"; - case 950 : return "big5"; - case 20127 : return "us-ascii"; - case 20269 : return "iso-6937"; - case 20865 : return "iso-8859-15"; - case 20866 : return "koi8-r"; - case 21866 : return "koi8-u"; - case 28591 : return "iso-8859-1"; - case 28592 : return "iso-8859-2"; - case 28595 : return "iso-8859-5"; - case 28596 : return "iso-8859-6"; - case 28597 : return "iso-8859-7"; - case 28598 : return "iso-8859-8"; - case 28599 : return "iso-8859-9"; - case 50220 : return "iso-2022-jp"; - case 50221 : return "csiso2022jp"; - case 51932 : return "euc-jp"; - case 51949 : return "euc-kr"; - case 65000 : return "utf-7"; - case 65001 : return "utf-8"; - default : - snprintf(buffer, sizeof(buffer), "windows-%d", cp); - return buffer; - } - return NULL; -} - - 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** extra_mime_headers) { char boundary[60]; @@ -1075,28 +1050,30 @@ int attach_num; time_t em_time; char *c_time; - char *headers = (item->email->header) ? item->email->header : *extra_mime_headers; + char *headers = NULL; int has_from, has_subject, has_to, has_cc, has_date, has_msgid; has_from = has_subject = has_to = has_cc = has_date = has_msgid = 0; DEBUG_ENT("write_normal_email"); + pst_convert_utf8_null(item, &item->email->header); + headers = (item->email->header.str) ? item->email->header.str : *extra_mime_headers; + // setup default body character set and report type - snprintf(body_charset, sizeof(body_charset), "%s", - (item->body_charset) ? item->body_charset : - (item->message_codepage) ? codepage(item->message_codepage) : - (item->internet_cpid) ? codepage(item->internet_cpid) : - "utf-8"); + strncpy(body_charset, pst_default_charset(item), sizeof(body_charset)); + body_charset[sizeof(body_charset)-1] = '\0'; body_report[0] = '\0'; // setup default sender - if (item->email->sender_address && strchr(item->email->sender_address, '@')) { - temp = item->email->sender_address; + pst_convert_utf8(item, &item->email->sender_address); + if (item->email->sender_address.str && strchr(item->email->sender_address.str, '@')) { + temp = item->email->sender_address.str; sender_known = 1; } else { temp = "MAILER-DAEMON"; } - snprintf(sender, sizeof(sender), "%s", temp); + strncpy(sender, temp, sizeof(sender)); + sender[sizeof(sender)-1] = '\0'; // convert the sent date if it exists, or set it to a fixed date if (item->email->sent_date) { @@ -1171,8 +1148,9 @@ 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 && item->subject.str) { + pst_convert_utf8(item, &item->subject); + DEBUG_EMAIL(("item->subject = %s\n", item->subject.str)); } if (mode != MODE_SEPARATE) { @@ -1195,23 +1173,25 @@ // create required header fields that are not already written if (!has_from) { - fprintf(f_output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name, sender); + fprintf(f_output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name.str, sender); } if (!has_subject) { - if (item->email->subject && item->email->subject->subj) { - fprintf(f_output, "Subject: %s\n", item->email->subject->subj); + if (item->subject.str) { + fprintf(f_output, "Subject: %s\n", item->subject.str); } else { fprintf(f_output, "Subject: \n"); } } - if (!has_to && item->email->sentto_address) { - fprintf(f_output, "To: %s\n", item->email->sentto_address); + if (!has_to && item->email->sentto_address.str) { + pst_convert_utf8(item, &item->email->sentto_address); + fprintf(f_output, "To: %s\n", item->email->sentto_address.str); } - if (!has_cc && item->email->cc_address) { - fprintf(f_output, "Cc: %s\n", item->email->cc_address); + if (!has_cc && item->email->cc_address.str) { + pst_convert_utf8(item, &item->email->cc_address); + fprintf(f_output, "Cc: %s\n", item->email->cc_address.str); } if (!has_date && item->email->sent_date) { @@ -1220,19 +1200,22 @@ fprintf(f_output, "Date: %s\n", c_time); } - if (!has_msgid && item->email->messageid) { - fprintf(f_output, "Message-Id: %s\n", item->email->messageid); + if (!has_msgid && item->email->messageid.str) { + pst_convert_utf8(item, &item->email->messageid); + fprintf(f_output, "Message-Id: %s\n", item->email->messageid.str); } // add forensic headers to capture some .pst stuff that is not really // needed or used by mail clients - if (item->email->sender_address && !strchr(item->email->sender_address, '@') - && strcmp(item->email->sender_address, ".")) { - fprintf(f_output, "X-libpst-forensic-sender: %s\n", item->email->sender_address); + pst_convert_utf8_null(item, &item->email->sender_address); + if (item->email->sender_address.str && !strchr(item->email->sender_address.str, '@') + && strcmp(item->email->sender_address.str, ".")) { + fprintf(f_output, "X-libpst-forensic-sender: %s\n", item->email->sender_address.str); } - if (item->email->bcc_address) { - fprintf(f_output, "X-libpst-forensic-bcc: %s\n", item->email->bcc_address); + 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); } // add our own mime headers @@ -1253,18 +1236,18 @@ fprintf(f_output, "\n"); // end of headers, start of body // now dump the body parts - if (item->email->body) { - write_body_part(f_output, item->email->body, item->email->body_was_unicode, "text/plain", body_charset, boundary, pst); + if (item->body.str) { + write_body_part(f_output, &item->body, "text/plain", body_charset, boundary, pst); } - if ((item->email->report_text) && (body_report[0] != '\0')) { - write_body_part(f_output, item->email->report_text, item->email->report_was_unicode, "text/plain", body_charset, boundary, pst); + if ((item->email->report_text.str) && (body_report[0] != '\0')) { + write_body_part(f_output, &item->email->report_text, "text/plain", body_charset, boundary, pst); fprintf(f_output, "\n"); } - if (item->email->htmlbody) { - find_html_charset(item->email->htmlbody, body_charset, sizeof(body_charset)); - write_body_part(f_output, item->email->htmlbody, item->email->htmlbody_was_unicode, "text/html", body_charset, boundary, pst); + if (item->email->htmlbody.str) { + find_html_charset(item->email->htmlbody.str, body_charset, sizeof(body_charset)); + write_body_part(f_output, &item->email->htmlbody, "text/html", body_charset, boundary, pst); } if (item->email->rtf_compressed && save_rtf) { @@ -1274,8 +1257,10 @@ attach->next = item->attach; item->attach = attach; attach->data = lzfu_decompress(item->email->rtf_compressed, item->email->rtf_compressed_size, &attach->size); - attach->filename2 = strdup(RTF_ATTACH_NAME); - attach->mimetype = strdup(RTF_ATTACH_TYPE); + attach->filename2.str = strdup(RTF_ATTACH_NAME); + attach->filename2.is_utf8 = 1; + attach->mimetype.str = strdup(RTF_ATTACH_TYPE); + attach->mimetype.is_utf8 = 1; } if (item->email->encrypted_body || item->email->encrypted_htmlbody) { @@ -1311,8 +1296,11 @@ pst_item_attach* attach; attach_num = 0; for (attach = item->attach; attach; attach = attach->next) { + pst_convert_utf8_null(item, &attach->filename1); + pst_convert_utf8_null(item, &attach->filename2); + pst_convert_utf8_null(item, &attach->mimetype); DEBUG_EMAIL(("Attempting Attachment encoding\n")); - if (!attach->data && attach->mimetype && !strcmp(attach->mimetype, RFC822)) { + if (!attach->data && attach->mimetype.str && !strcmp(attach->mimetype.str, RFC822)) { DEBUG_EMAIL(("seem to have special embedded message attachment\n")); find_rfc822_headers(extra_mime_headers); write_embedded_message(f_output, attach, boundary, pst, extra_mime_headers); @@ -1334,95 +1322,149 @@ } -void write_vcard(FILE* f_output, pst_item_contact* contact, char comment[]) +void write_vcard(FILE* f_output, pst_item *item, pst_item_contact* contact, char comment[]) { // We can only call rfc escape once per printf, since the second call // may free the buffer returned by the first call. // I had tried to place those into a single printf - Carl. DEBUG_ENT("write_vcard"); + + // make everything utf8 + pst_convert_utf8_null(item, &contact->fullname); + pst_convert_utf8_null(item, &contact->surname); + pst_convert_utf8_null(item, &contact->first_name); + pst_convert_utf8_null(item, &contact->middle_name); + pst_convert_utf8_null(item, &contact->display_name_prefix); + pst_convert_utf8_null(item, &contact->suffix); + pst_convert_utf8_null(item, &contact->nickname); + pst_convert_utf8_null(item, &contact->address1); + pst_convert_utf8_null(item, &contact->address2); + pst_convert_utf8_null(item, &contact->address3); + pst_convert_utf8_null(item, &contact->home_po_box); + pst_convert_utf8_null(item, &contact->home_street); + pst_convert_utf8_null(item, &contact->home_city); + pst_convert_utf8_null(item, &contact->home_state); + pst_convert_utf8_null(item, &contact->home_postal_code); + pst_convert_utf8_null(item, &contact->home_country); + pst_convert_utf8_null(item, &contact->home_address); + pst_convert_utf8_null(item, &contact->business_po_box); + pst_convert_utf8_null(item, &contact->business_street); + pst_convert_utf8_null(item, &contact->business_city); + pst_convert_utf8_null(item, &contact->business_state); + pst_convert_utf8_null(item, &contact->business_postal_code); + pst_convert_utf8_null(item, &contact->business_country); + pst_convert_utf8_null(item, &contact->business_address); + pst_convert_utf8_null(item, &contact->other_po_box); + pst_convert_utf8_null(item, &contact->other_street); + pst_convert_utf8_null(item, &contact->other_city); + pst_convert_utf8_null(item, &contact->other_state); + pst_convert_utf8_null(item, &contact->other_postal_code); + pst_convert_utf8_null(item, &contact->other_country); + pst_convert_utf8_null(item, &contact->other_address); + pst_convert_utf8_null(item, &contact->business_fax); + pst_convert_utf8_null(item, &contact->business_phone); + pst_convert_utf8_null(item, &contact->business_phone2); + pst_convert_utf8_null(item, &contact->car_phone); + pst_convert_utf8_null(item, &contact->home_fax); + pst_convert_utf8_null(item, &contact->home_phone); + pst_convert_utf8_null(item, &contact->home_phone2); + pst_convert_utf8_null(item, &contact->isdn_phone); + pst_convert_utf8_null(item, &contact->mobile_phone); + pst_convert_utf8_null(item, &contact->other_phone); + pst_convert_utf8_null(item, &contact->pager_phone); + pst_convert_utf8_null(item, &contact->primary_fax); + pst_convert_utf8_null(item, &contact->primary_phone); + pst_convert_utf8_null(item, &contact->radio_phone); + pst_convert_utf8_null(item, &contact->telex); + pst_convert_utf8_null(item, &contact->job_title); + pst_convert_utf8_null(item, &contact->profession); + pst_convert_utf8_null(item, &contact->assistant_name); + pst_convert_utf8_null(item, &contact->assistant_phone); + pst_convert_utf8_null(item, &contact->company_name); + // the specification I am following is (hopefully) RFC2426 vCard Mime Directory Profile fprintf(f_output, "BEGIN:VCARD\n"); - fprintf(f_output, "FN:%s\n", pst_rfc2426_escape(contact->fullname)); + fprintf(f_output, "FN:%s\n", pst_rfc2426_escape(contact->fullname.str)); //fprintf(f_output, "N:%s;%s;%s;%s;%s\n", - fprintf(f_output, "N:%s;", (!contact->surname) ? "" : pst_rfc2426_escape(contact->surname)); - fprintf(f_output, "%s;", (!contact->first_name) ? "" : pst_rfc2426_escape(contact->first_name)); - fprintf(f_output, "%s;", (!contact->middle_name) ? "" : pst_rfc2426_escape(contact->middle_name)); - fprintf(f_output, "%s;", (!contact->display_name_prefix) ? "" : pst_rfc2426_escape(contact->display_name_prefix)); - fprintf(f_output, "%s\n", (!contact->suffix) ? "" : pst_rfc2426_escape(contact->suffix)); + fprintf(f_output, "N:%s;", (!contact->surname.str) ? "" : pst_rfc2426_escape(contact->surname.str)); + fprintf(f_output, "%s;", (!contact->first_name.str) ? "" : pst_rfc2426_escape(contact->first_name.str)); + fprintf(f_output, "%s;", (!contact->middle_name.str) ? "" : pst_rfc2426_escape(contact->middle_name.str)); + fprintf(f_output, "%s;", (!contact->display_name_prefix.str) ? "" : pst_rfc2426_escape(contact->display_name_prefix.str)); + fprintf(f_output, "%s\n", (!contact->suffix.str) ? "" : pst_rfc2426_escape(contact->suffix.str)); - if (contact->nickname) - fprintf(f_output, "NICKNAME:%s\n", pst_rfc2426_escape(contact->nickname)); - if (contact->address1) - fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address1)); - if (contact->address2) - fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address2)); - if (contact->address3) - fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address3)); + if (contact->nickname.str) + fprintf(f_output, "NICKNAME:%s\n", pst_rfc2426_escape(contact->nickname.str)); + if (contact->address1.str) + fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address1.str)); + if (contact->address2.str) + fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address2.str)); + if (contact->address3.str) + fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address3.str)); if (contact->birthday) fprintf(f_output, "BDAY:%s\n", pst_rfc2425_datetime_format(contact->birthday)); - if (contact->home_address) { + if (contact->home_address.str) { //fprintf(f_output, "ADR;TYPE=home:%s;%s;%s;%s;%s;%s;%s\n", - fprintf(f_output, "ADR;TYPE=home:%s;", (!contact->home_po_box) ? "" : pst_rfc2426_escape(contact->home_po_box)); + fprintf(f_output, "ADR;TYPE=home:%s;", (!contact->home_po_box.str) ? "" : pst_rfc2426_escape(contact->home_po_box.str)); fprintf(f_output, "%s;", ""); // extended Address - fprintf(f_output, "%s;", (!contact->home_street) ? "" : pst_rfc2426_escape(contact->home_street)); - fprintf(f_output, "%s;", (!contact->home_city) ? "" : pst_rfc2426_escape(contact->home_city)); - fprintf(f_output, "%s;", (!contact->home_state) ? "" : pst_rfc2426_escape(contact->home_state)); - fprintf(f_output, "%s;", (!contact->home_postal_code) ? "" : pst_rfc2426_escape(contact->home_postal_code)); - fprintf(f_output, "%s\n", (!contact->home_country) ? "" : pst_rfc2426_escape(contact->home_country)); - fprintf(f_output, "LABEL;TYPE=home:%s\n", pst_rfc2426_escape(contact->home_address)); + fprintf(f_output, "%s;", (!contact->home_street.str) ? "" : pst_rfc2426_escape(contact->home_street.str)); + fprintf(f_output, "%s;", (!contact->home_city.str) ? "" : pst_rfc2426_escape(contact->home_city.str)); + fprintf(f_output, "%s;", (!contact->home_state.str) ? "" : pst_rfc2426_escape(contact->home_state.str)); + fprintf(f_output, "%s;", (!contact->home_postal_code.str) ? "" : pst_rfc2426_escape(contact->home_postal_code.str)); + fprintf(f_output, "%s\n", (!contact->home_country.str) ? "" : pst_rfc2426_escape(contact->home_country.str)); + fprintf(f_output, "LABEL;TYPE=home:%s\n", pst_rfc2426_escape(contact->home_address.str)); } - if (contact->business_address) { + if (contact->business_address.str) { //fprintf(f_output, "ADR;TYPE=work:%s;%s;%s;%s;%s;%s;%s\n", - fprintf(f_output, "ADR;TYPE=work:%s;", (!contact->business_po_box) ? "" : pst_rfc2426_escape(contact->business_po_box)); + fprintf(f_output, "ADR;TYPE=work:%s;", (!contact->business_po_box.str) ? "" : pst_rfc2426_escape(contact->business_po_box.str)); fprintf(f_output, "%s;", ""); // extended Address - fprintf(f_output, "%s;", (!contact->business_street) ? "" : pst_rfc2426_escape(contact->business_street)); - fprintf(f_output, "%s;", (!contact->business_city) ? "" : pst_rfc2426_escape(contact->business_city)); - fprintf(f_output, "%s;", (!contact->business_state) ? "" : pst_rfc2426_escape(contact->business_state)); - fprintf(f_output, "%s;", (!contact->business_postal_code) ? "" : pst_rfc2426_escape(contact->business_postal_code)); - fprintf(f_output, "%s\n", (!contact->business_country) ? "" : pst_rfc2426_escape(contact->business_country)); - fprintf(f_output, "LABEL;TYPE=work:%s\n", pst_rfc2426_escape(contact->business_address)); + fprintf(f_output, "%s;", (!contact->business_street.str) ? "" : pst_rfc2426_escape(contact->business_street.str)); + fprintf(f_output, "%s;", (!contact->business_city.str) ? "" : pst_rfc2426_escape(contact->business_city.str)); + fprintf(f_output, "%s;", (!contact->business_state.str) ? "" : pst_rfc2426_escape(contact->business_state.str)); + fprintf(f_output, "%s;", (!contact->business_postal_code.str) ? "" : pst_rfc2426_escape(contact->business_postal_code.str)); + fprintf(f_output, "%s\n", (!contact->business_country.str) ? "" : pst_rfc2426_escape(contact->business_country.str)); + fprintf(f_output, "LABEL;TYPE=work:%s\n", pst_rfc2426_escape(contact->business_address.str)); } - if (contact->other_address) { + if (contact->other_address.str) { //fprintf(f_output, "ADR;TYPE=postal:%s;%s;%s;%s;%s;%s;%s\n", - fprintf(f_output, "ADR;TYPE=postal:%s;",(!contact->other_po_box) ? "" : pst_rfc2426_escape(contact->other_po_box)); + fprintf(f_output, "ADR;TYPE=postal:%s;",(!contact->other_po_box.str) ? "" : pst_rfc2426_escape(contact->other_po_box.str)); fprintf(f_output, "%s;", ""); // extended Address - fprintf(f_output, "%s;", (!contact->other_street) ? "" : pst_rfc2426_escape(contact->other_street)); - fprintf(f_output, "%s;", (!contact->other_city) ? "" : pst_rfc2426_escape(contact->other_city)); - fprintf(f_output, "%s;", (!contact->other_state) ? "" : pst_rfc2426_escape(contact->other_state)); - fprintf(f_output, "%s;", (!contact->other_postal_code) ? "" : pst_rfc2426_escape(contact->other_postal_code)); - fprintf(f_output, "%s\n", (!contact->other_country) ? "" : pst_rfc2426_escape(contact->other_country)); - fprintf(f_output, "LABEL;TYPE=postal:%s\n", pst_rfc2426_escape(contact->other_address)); + fprintf(f_output, "%s;", (!contact->other_street.str) ? "" : pst_rfc2426_escape(contact->other_street.str)); + fprintf(f_output, "%s;", (!contact->other_city.str) ? "" : pst_rfc2426_escape(contact->other_city.str)); + fprintf(f_output, "%s;", (!contact->other_state.str) ? "" : pst_rfc2426_escape(contact->other_state.str)); + fprintf(f_output, "%s;", (!contact->other_postal_code.str) ? "" : pst_rfc2426_escape(contact->other_postal_code.str)); + fprintf(f_output, "%s\n", (!contact->other_country.str) ? "" : pst_rfc2426_escape(contact->other_country.str)); + fprintf(f_output, "LABEL;TYPE=postal:%s\n", pst_rfc2426_escape(contact->other_address.str)); } - if (contact->business_fax) fprintf(f_output, "TEL;TYPE=work,fax:%s\n", pst_rfc2426_escape(contact->business_fax)); - if (contact->business_phone) fprintf(f_output, "TEL;TYPE=work,voice:%s\n", pst_rfc2426_escape(contact->business_phone)); - if (contact->business_phone2) fprintf(f_output, "TEL;TYPE=work,voice:%s\n", pst_rfc2426_escape(contact->business_phone2)); - if (contact->car_phone) fprintf(f_output, "TEL;TYPE=car,voice:%s\n", pst_rfc2426_escape(contact->car_phone)); - if (contact->home_fax) fprintf(f_output, "TEL;TYPE=home,fax:%s\n", pst_rfc2426_escape(contact->home_fax)); - if (contact->home_phone) fprintf(f_output, "TEL;TYPE=home,voice:%s\n", pst_rfc2426_escape(contact->home_phone)); - if (contact->home_phone2) fprintf(f_output, "TEL;TYPE=home,voice:%s\n", pst_rfc2426_escape(contact->home_phone2)); - if (contact->isdn_phone) fprintf(f_output, "TEL;TYPE=isdn:%s\n", pst_rfc2426_escape(contact->isdn_phone)); - if (contact->mobile_phone) fprintf(f_output, "TEL;TYPE=cell,voice:%s\n", pst_rfc2426_escape(contact->mobile_phone)); - if (contact->other_phone) fprintf(f_output, "TEL;TYPE=msg:%s\n", pst_rfc2426_escape(contact->other_phone)); - if (contact->pager_phone) fprintf(f_output, "TEL;TYPE=pager:%s\n", pst_rfc2426_escape(contact->pager_phone)); - if (contact->primary_fax) fprintf(f_output, "TEL;TYPE=fax,pref:%s\n", pst_rfc2426_escape(contact->primary_fax)); - if (contact->primary_phone) fprintf(f_output, "TEL;TYPE=phone,pref:%s\n", pst_rfc2426_escape(contact->primary_phone)); - if (contact->radio_phone) fprintf(f_output, "TEL;TYPE=pcs:%s\n", pst_rfc2426_escape(contact->radio_phone)); - if (contact->telex) fprintf(f_output, "TEL;TYPE=bbs:%s\n", pst_rfc2426_escape(contact->telex)); - if (contact->job_title) fprintf(f_output, "TITLE:%s\n", pst_rfc2426_escape(contact->job_title)); - if (contact->profession) fprintf(f_output, "ROLE:%s\n", pst_rfc2426_escape(contact->profession)); - if (contact->assistant_name || contact->assistant_phone) { + if (contact->business_fax.str) fprintf(f_output, "TEL;TYPE=work,fax:%s\n", pst_rfc2426_escape(contact->business_fax.str)); + if (contact->business_phone.str) fprintf(f_output, "TEL;TYPE=work,voice:%s\n", pst_rfc2426_escape(contact->business_phone.str)); + if (contact->business_phone2.str) fprintf(f_output, "TEL;TYPE=work,voice:%s\n", pst_rfc2426_escape(contact->business_phone2.str)); + if (contact->car_phone.str) fprintf(f_output, "TEL;TYPE=car,voice:%s\n", pst_rfc2426_escape(contact->car_phone.str)); + if (contact->home_fax.str) fprintf(f_output, "TEL;TYPE=home,fax:%s\n", pst_rfc2426_escape(contact->home_fax.str)); + if (contact->home_phone.str) fprintf(f_output, "TEL;TYPE=home,voice:%s\n", pst_rfc2426_escape(contact->home_phone.str)); + if (contact->home_phone2.str) fprintf(f_output, "TEL;TYPE=home,voice:%s\n", pst_rfc2426_escape(contact->home_phone2.str)); + if (contact->isdn_phone.str) fprintf(f_output, "TEL;TYPE=isdn:%s\n", pst_rfc2426_escape(contact->isdn_phone.str)); + if (contact->mobile_phone.str) fprintf(f_output, "TEL;TYPE=cell,voice:%s\n", pst_rfc2426_escape(contact->mobile_phone.str)); + if (contact->other_phone.str) fprintf(f_output, "TEL;TYPE=msg:%s\n", pst_rfc2426_escape(contact->other_phone.str)); + if (contact->pager_phone.str) fprintf(f_output, "TEL;TYPE=pager:%s\n", pst_rfc2426_escape(contact->pager_phone.str)); + if (contact->primary_fax.str) fprintf(f_output, "TEL;TYPE=fax,pref:%s\n", pst_rfc2426_escape(contact->primary_fax.str)); + if (contact->primary_phone.str) fprintf(f_output, "TEL;TYPE=phone,pref:%s\n", pst_rfc2426_escape(contact->primary_phone.str)); + if (contact->radio_phone.str) fprintf(f_output, "TEL;TYPE=pcs:%s\n", pst_rfc2426_escape(contact->radio_phone.str)); + if (contact->telex.str) fprintf(f_output, "TEL;TYPE=bbs:%s\n", pst_rfc2426_escape(contact->telex.str)); + if (contact->job_title.str) fprintf(f_output, "TITLE:%s\n", pst_rfc2426_escape(contact->job_title.str)); + if (contact->profession.str) fprintf(f_output, "ROLE:%s\n", pst_rfc2426_escape(contact->profession.str)); + if (contact->assistant_name.str || contact->assistant_phone.str) { fprintf(f_output, "AGENT:BEGIN:VCARD\n"); - if (contact->assistant_name) fprintf(f_output, "FN:%s\n", pst_rfc2426_escape(contact->assistant_name)); - if (contact->assistant_phone) fprintf(f_output, "TEL:%s\n", pst_rfc2426_escape(contact->assistant_phone)); + if (contact->assistant_name.str) fprintf(f_output, "FN:%s\n", pst_rfc2426_escape(contact->assistant_name.str)); + if (contact->assistant_phone.str) fprintf(f_output, "TEL:%s\n", pst_rfc2426_escape(contact->assistant_phone.str)); } - if (contact->company_name) fprintf(f_output, "ORG:%s\n", pst_rfc2426_escape(contact->company_name)); - if (comment) fprintf(f_output, "NOTE:%s\n", pst_rfc2426_escape(comment)); + if (contact->company_name.str) fprintf(f_output, "ORG:%s\n", pst_rfc2426_escape(contact->company_name.str)); + if (comment) fprintf(f_output, "NOTE:%s\n", pst_rfc2426_escape(comment)); fprintf(f_output, "VERSION: 3.0\n"); fprintf(f_output, "END:VCARD\n\n"); @@ -1430,31 +1472,29 @@ } -void write_appointment(FILE* f_output, pst_item_appointment* appointment, - pst_item_email* email, FILETIME* create_date, FILETIME* modify_date) +void write_appointment(FILE* f_output, pst_item *item, pst_item_appointment* appointment, + FILETIME* create_date, FILETIME* modify_date) { + // make everything utf8 + pst_convert_utf8_null(item, &item->subject); + pst_convert_utf8_null(item, &item->body); + pst_convert_utf8_null(item, &appointment->location); + fprintf(f_output, "BEGIN:VEVENT\n"); if (create_date) - fprintf(f_output, "CREATED:%s\n", - pst_rfc2445_datetime_format(create_date)); + fprintf(f_output, "CREATED:%s\n", pst_rfc2445_datetime_format(create_date)); if (modify_date) - fprintf(f_output, "LAST-MOD:%s\n", - pst_rfc2445_datetime_format(modify_date)); - if (email && email->subject) - fprintf(f_output, "SUMMARY:%s\n", - pst_rfc2426_escape(email->subject->subj)); - if (email && email->body) - fprintf(f_output, "DESCRIPTION:%s\n", - pst_rfc2426_escape(email->body)); + fprintf(f_output, "LAST-MOD:%s\n", pst_rfc2445_datetime_format(modify_date)); + if (item->subject.str) + fprintf(f_output, "SUMMARY:%s\n", pst_rfc2426_escape(item->subject.str)); + if (item->body.str) + fprintf(f_output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->body.str)); if (appointment && appointment->start) - fprintf(f_output, "DTSTART;VALUE=DATE-TIME:%s\n", - pst_rfc2445_datetime_format(appointment->start)); + fprintf(f_output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(appointment->start)); if (appointment && appointment->end) - fprintf(f_output, "DTEND;VALUE=DATE-TIME:%s\n", - pst_rfc2445_datetime_format(appointment->end)); - if (appointment && appointment->location) - fprintf(f_output, "LOCATION:%s\n", - pst_rfc2426_escape(appointment->location)); + fprintf(f_output, "DTEND;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(appointment->end)); + if (appointment && appointment->location.str) + fprintf(f_output, "LOCATION:%s\n", pst_rfc2426_escape(appointment->location.str)); if (appointment) { switch (appointment->showas) { case PST_FREEBUSY_TENTATIVE: @@ -1510,6 +1550,7 @@ void create_enter_dir(struct file_ll* f, pst_item *item) { + pst_convert_utf8(item, &item->file_as); f->email_count = 0; f->skip_count = 0; f->type = item->type; @@ -1517,22 +1558,22 @@ DEBUG_ENT("create_enter_dir"); if (mode == MODE_KMAIL) - f->name = mk_kmail_dir(item->file_as); //create directory and form filename + f->name = mk_kmail_dir(item->file_as.str); //create directory and form filename else if (mode == MODE_RECURSE) - f->name = mk_recurse_dir(item->file_as); + f->name = mk_recurse_dir(item->file_as.str); else if (mode == MODE_SEPARATE) { // do similar stuff to recurse here. - mk_separate_dir(item->file_as); + mk_separate_dir(item->file_as.str); f->name = (char*) xmalloc(10); memset(f->name, 0, 10); // sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->email_count); } else { - f->name = (char*) xmalloc(strlen(item->file_as)+strlen(OUTPUT_TEMPLATE)+1); - sprintf(f->name, OUTPUT_TEMPLATE, item->file_as); + f->name = (char*) xmalloc(strlen(item->file_as.str)+strlen(OUTPUT_TEMPLATE)+1); + sprintf(f->name, OUTPUT_TEMPLATE, item->file_as.str); } - f->dname = (char*) xmalloc(strlen(item->file_as)+1); - strcpy(f->dname, item->file_as); + f->dname = (char*) xmalloc(strlen(item->file_as.str)+1); + strcpy(f->dname, item->file_as.str); if (overwrite != 1) { int x = 0; @@ -1559,7 +1600,7 @@ } } - DEBUG_MAIN(("f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as)); + DEBUG_MAIN(("f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as.str)); if (mode != MODE_SEPARATE) { check_filename(f->name); if (!(f->output = fopen(f->name, "w"))) { diff -r 06aa84023b48 -r cda7c812ec01 src/vbuf.c --- a/src/vbuf.c Thu Mar 05 08:23:32 2009 -0800 +++ b/src/vbuf.c Sun Mar 08 14:35:26 2009 -0700 @@ -43,16 +43,18 @@ static int unicode_up = 0; static iconv_t i16to8; static const char *target_charset = NULL; -static int target_open = 0; -static iconv_t i8totarget; +static int target_open_from = 0; +static int target_open_to = 0; +static iconv_t i8totarget = (iconv_t)-1; +static iconv_t target2i8 = (iconv_t)-1; void unicode_init() { if (unicode_up) unicode_close(); - i16to8 = iconv_open("UTF-8", "UTF-16LE"); + i16to8 = iconv_open("utf-8", "utf-16le"); if (i16to8 == (iconv_t)-1) { - fprintf(stderr, "Couldn't open iconv descriptor for UTF-16LE to UTF-8.\n"); + WARN(("Couldn't open iconv descriptor for utf-16le to utf-8.\n")); exit(1); } unicode_up = 1; @@ -62,12 +64,12 @@ void unicode_close() { iconv_close(i16to8); - if (target_open) { - iconv_close(i8totarget); - free((char *)target_charset); - target_charset = NULL; - target_open = 0; - } + if (target_open_from) iconv_close(i8totarget); + if (target_open_to) iconv_close(target2i8); + if (target_charset) free((char *)target_charset); + target_charset = NULL; + target_open_from = 0; + target_open_to = 0; unicode_up = 0; } @@ -125,39 +127,47 @@ } -size_t vb_utf8to8bit(vbuf *dest, const char *inbuf, int iblen, const char* charset) +static void open_targets(const char* charset); +static void open_targets(const char* charset) +{ + if (!target_charset || strcasecmp(target_charset, charset)) { + if (target_open_from) iconv_close(i8totarget); + if (target_open_to) iconv_close(target2i8); + if (target_charset) free((char *)target_charset); + target_charset = strdup(charset); + target_open_from = 1; + target_open_to = 1; + i8totarget = iconv_open(target_charset, "utf-8"); + if (i8totarget == (iconv_t)-1) { + target_open_from = 0; + WARN(("Couldn't open iconv descriptor for utf-8 to %s.\n", target_charset)); + } + target2i8 = iconv_open("utf-8", target_charset); + if (target2i8 == (iconv_t)-1) { + target_open_to = 0; + WARN(("Couldn't open iconv descriptor for %s to utf-8.\n", target_charset)); + } + } +} + + +static size_t sbcs_conversion(vbuf *dest, const char *inbuf, int iblen, iconv_t conversion); +static size_t sbcs_conversion(vbuf *dest, const char *inbuf, int iblen, iconv_t conversion) { size_t inbytesleft = iblen; size_t icresult = (size_t)-1; size_t outbytesleft = 0; char *outbuf = NULL; - if (!target_charset || strcasecmp(target_charset, charset)) { - if (target_open) { - iconv_close(i8totarget); - free((char *)target_charset); - } - target_charset = strdup(charset); - target_open = 1; - i8totarget = iconv_open(target_charset, "UTF-8"); - if (i8totarget == (iconv_t)-1) { - target_open = 0; - fprintf(stderr, "Couldn't open iconv descriptor for UTF-8 to %s.\n", target_charset); - return (size_t)-1; - } - } - - if (!target_open) return (size_t)-1; // previous failure to open the target - - if (2 > dest->blen) vbresize(dest, 2); + vbresize(dest, 2*iblen); dest->dlen = 0; do { outbytesleft = dest->blen - dest->dlen; outbuf = dest->b + dest->dlen; - icresult = iconv(i8totarget, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft); + icresult = iconv(conversion, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft); dest->dlen = outbuf - dest->b; - vbgrow(dest, 20); + if (inbytesleft) vbgrow(dest, 2*inbytesleft); } while ((size_t)-1 == icresult && E2BIG == errno); if (icresult == (size_t)-1) { @@ -169,6 +179,22 @@ } +size_t vb_utf8to8bit(vbuf *dest, const char *inbuf, int iblen, const char* charset) +{ + open_targets(charset); + if (!target_open_from) return (size_t)-1; // failure to open the target + return sbcs_conversion(dest, inbuf, iblen, i8totarget); +} + + +size_t vb_8bit2utf8(vbuf *dest, const char *inbuf, int iblen, const char* charset) +{ + open_targets(charset); + if (!target_open_to) return (size_t)-1; // failure to open the target + return sbcs_conversion(dest, inbuf, iblen, target2i8); +} + + vbuf *vballoc(size_t len) { struct varbuf *result = malloc(sizeof(struct varbuf)); @@ -226,20 +252,6 @@ } -//void vbdump( vbuf *vb ) // TODO: to stdout? Yuck -//{ -// printf("vb dump-------------\n"); -// printf("dlen: %d\n", vb->dlen ); -// printf("blen: %d\n", vb->blen ); -// printf("b - buf: %d\n", vb->b - vb->buf ); -// printf("buf:\n"); -// hexdump( vb->buf, 0, vb->blen, 1 ); -// printf("b:\n"); -// hexdump( vb->b, 0, vb->dlen, 1 ); -// printf("^^^^^^^^^^^^^^^^^^^^\n"); -//} - - void vbgrow(struct varbuf *vb, size_t len) // out: vbavail(vb) >= len, data are preserved { if (0 == len) diff -r 06aa84023b48 -r cda7c812ec01 src/vbuf.h --- a/src/vbuf.h Thu Mar 05 08:23:32 2009 -0800 +++ b/src/vbuf.h Sun Mar 08 14:35:26 2009 -0700 @@ -88,6 +88,7 @@ void unicode_close(); size_t vb_utf16to8(vbuf *dest, const char *inbuf, int iblen); size_t vb_utf8to8bit(vbuf *dest, const char *inbuf, int iblen, const char* charset); +size_t vb_8bit2utf8(vbuf *dest, const char *inbuf, int iblen, const char* charset); int vb_skipline( struct varbuf *vb ); // in: vb->b == "stuff\nmore_stuff"; out: vb->b == "more_stuff"