# HG changeset patch # User Carl Byington # Date 1244486979 25200 # Node ID 94bde95d7e18c7e584d106f6d407f7f3c0331512 # Parent 2d1111fd70cff87434320419e832a1db03c9e16b the shared library interface should now be thread safe diff -r 2d1111fd70cf -r 94bde95d7e18 ChangeLog --- a/ChangeLog Sat Jun 06 13:53:34 2009 -0700 +++ b/ChangeLog Mon Jun 08 11:49:39 2009 -0700 @@ -9,7 +9,6 @@ * removed contact->access_method since we don't have a mapi element for it. * changed pst_attach_to_mem to return pst_binary structure. * decode more recurrence mapi elements. - * change some interfaces to be thread safe. * readpst changes for parallel operation on multi processor machines. * remove readpstlog - the debug log files are now plain ascii. Add locking if needed so parallel jobs can produce debug logs. @@ -17,6 +16,7 @@ thread safe. * make nested mime multipart/alternative to hold the text/html parts so the topmost level is almost always multipart/mixed. + * the shared library interface should now be thread safe. LibPST 0.6.37 (2009-04-17) =============================== diff -r 2d1111fd70cf -r 94bde95d7e18 libpst.spec.in --- a/libpst.spec.in Sat Jun 06 13:53:34 2009 -0700 +++ b/libpst.spec.in Mon Jun 08 11:49:39 2009 -0700 @@ -148,12 +148,13 @@ %changelog -* Mon Apr 20 2009 Carl Byington - 0.6.38-1 +* Mon Jun 08 2009 Carl Byington - 0.6.38-1 - add python interface to the shared library. - bump soname to version 4 for many changes to the interface. - better decoding of recurrence data in appointments. - remove readpstlog since debug log files are now plain text. - add readpst -j option for parallel jobs for each folder. +- make nested mime multipart/alternative to hold the text/html parts. * Fri Apr 17 2009 Carl Byington - 0.6.37-1 - add pst_attach_to_mem() back into the shared library interface. diff -r 2d1111fd70cf -r 94bde95d7e18 python/python-libpst.cpp --- a/python/python-libpst.cpp Sat Jun 06 13:53:34 2009 -0700 +++ b/python/python-libpst.cpp Mon Jun 08 11:49:39 2009 -0700 @@ -120,7 +120,12 @@ } string pst::pst_rfc2426_escape(char *str) { - return ::pst_rfc2426_escape(str); + char *result = NULL; + size_t resultlen = 0; + char *rc = ::pst_rfc2426_escape(str, &result, &resultlen); + string rrc(rc); + if (result) free(result); + return rrc; } string pst::pst_rfc2425_datetime_format(const FILETIME *ft) { @@ -136,7 +141,8 @@ } string pst::pst_default_charset(pst_item *item) { - return ::pst_default_charset(item); + char buf[30]; + return string(::pst_default_charset(item, sizeof(buf), buf)); } void pst::pst_convert_utf8_null(pst_item *item, pst_string *str) { diff -r 2d1111fd70cf -r 94bde95d7e18 regression/regression-tests.bash --- a/regression/regression-tests.bash Sat Jun 06 13:53:34 2009 -0700 +++ b/regression/regression-tests.bash Mon Jun 08 11:49:39 2009 -0700 @@ -61,7 +61,7 @@ val="valgrind --leak-check=full" -val='' +#val='' pushd .. make || exit @@ -115,7 +115,7 @@ #dopst 16 hourig2.pst #dopst 17 hourig3.pst dopst 18 test-mac.pst - dopst 19 harris.pst + #dopst 19 harris.pst dopst 20 spam.pst dopst 21 rendgen.pst # single email appointment dopst 22 rendgen2.pst # email appointment with no termination date diff -r 2d1111fd70cf -r 94bde95d7e18 src/libpst.c --- a/src/libpst.c Sat Jun 06 13:53:34 2009 -0700 +++ b/src/libpst.c Mon Jun 08 11:49:39 2009 -0700 @@ -4143,9 +4143,9 @@ } -char* pst_rfc2426_escape(char *str) { - static char* buf = NULL; - static size_t buflen = 0; +char* pst_rfc2426_escape(char* str, char **buf, size_t* buflen) { + //static char* buf = NULL; + //static size_t buflen = 0; char *ret, *a, *b; size_t x = 0; int y, z; @@ -4162,12 +4162,12 @@ ret = str; else { x = strlen(str) + y - z + 1; // don't forget room for the NUL - if (x > buflen) { - buf = (char*) realloc(buf, x); - buflen = x; + if (x > *buflen) { + *buf = (char*) realloc(*buf, x); + *buflen = x; } a = str; - b = buf; + b = *buf; while (*a != '\0') { switch (*a) { case ',' : @@ -4190,7 +4190,7 @@ a++; } *b = '\0'; // NUL-terminate the string (buf) - ret = buf; + ret = *buf; } DEBUG_RET(); return ret; @@ -4247,12 +4247,13 @@ /** Convert a code page integer into a string suitable for iconv() * * @param cp the code page integer used in the pst file + * @param[in] buflen length of the output buffer + * @param[out] result pointer to output buffer, must be at least 30 bytes * @return pointer to a static buffer holding the string representation of the * equivalent iconv character set */ -static const char* codepage(int cp); -static const char* codepage(int cp) { - static char buffer[20]; +static const char* codepage(int cp, int buflen, char* result); +static const char* codepage(int cp, int buflen, char* result) { switch (cp) { case 932 : return "iso-2022-jp"; case 936 : return "gb2313"; @@ -4283,8 +4284,8 @@ case 65000 : return "utf-7"; case 65001 : return "utf-8"; default : - snprintf(buffer, sizeof(buffer), "windows-%d", cp); - return buffer; + snprintf(result, buflen, "windows-%d", cp); + return result; } return NULL; } @@ -4293,12 +4294,14 @@ /** Get the default character set for this item. This is used to find * the charset for pst_string elements that are not already in utf8 encoding. * @param item pointer to the mapi item of interest + * @param[in] buflen length of the output buffer + * @param[out] result pointer to output buffer, must be at least 30 bytes * @return default character set as a string useable by iconv() */ -const char* pst_default_charset(pst_item *item) { +const char* pst_default_charset(pst_item *item, int buflen, char* result) { return (item->body_charset.str) ? item->body_charset.str : - (item->message_codepage) ? codepage(item->message_codepage) : - (item->internet_cpid) ? codepage(item->internet_cpid) : + (item->message_codepage) ? codepage(item->message_codepage, buflen, result) : + (item->internet_cpid) ? codepage(item->internet_cpid, buflen, result) : "utf-8"; } @@ -4320,12 +4323,13 @@ * @param str pointer to the mapi string of interest */ void pst_convert_utf8(pst_item *item, pst_string *str) { + char buffer[30]; if (str->is_utf8) return; if (!str->str) { str->str = strdup(""); return; } - const char *charset = pst_default_charset(item); + const char *charset = pst_default_charset(item, sizeof(buffer), buffer); if (!strcasecmp("utf-8", charset)) return; // already utf8 DEBUG_ENT("pst_convert_utf8"); pst_vbuf *newer = pst_vballoc(2); diff -r 2d1111fd70cf -r 94bde95d7e18 src/libpst.h --- a/src/libpst.h Sat Jun 06 13:53:34 2009 -0700 +++ b/src/libpst.h Mon Jun 08 11:49:39 2009 -0700 @@ -1015,13 +1015,14 @@ /** Add any necessary escape characters for rfc2426 vcard format - * @param str pointer to input string + * @param[in] str pointer to input string + * @param[in,out] result pointer to a char* pointer that may be realloc'ed if needed + * @param[in,out] resultlen size of the result buffer * @return pointer to output string, either the input pointer if * there are no characters that need escapes, or a pointer - * to a different buffer containing the escaped string. In - * either case, you don't need to free this returned pointer. + * to a possibly realloc'ed result buffer. */ -char* pst_rfc2426_escape(char *str); +char* pst_rfc2426_escape(char* str, char** result, size_t* resultlen); /** Convert a FILETIME into rfc2425 date/time format 1953-10-15T23:10:00Z @@ -1035,7 +1036,7 @@ /** Convert a FILETIME into rfc2445 date/time format 19531015T231000Z - * @param[in] ft time to be converted + * @param[in] ft time to be converted * @param[in] buflen length of the output buffer * @param[out] result pointer to output buffer, must be at least 30 bytes * @return time in rfc2445 format @@ -1044,6 +1045,8 @@ /** Convert the current time rfc2445 date/time format 19531015T231000Z + * @param[in] buflen length of the output buffer + * @param[out] result pointer to output buffer, must be at least 30 bytes * @return time in rfc2445 format */ char* pst_rfc2445_datetime_format_now(int buflen, char* result); @@ -1051,10 +1054,12 @@ /** Get the default character set for this item. This is used to find * the charset for pst_string elements that are not already in utf8 encoding. - * @param item pointer to the mapi item of interest + * @param item pointer to the mapi item of interest + * @param[in] buflen length of the output buffer + * @param[out] result pointer to output buffer, must be at least 30 bytes * @return default character set as a string useable by iconv() */ -const char* pst_default_charset(pst_item *item); +const char* pst_default_charset(pst_item *item, int buflen, char* result); /** Convert str to utf8 if possible; null strings are preserved. diff -r 2d1111fd70cf -r 94bde95d7e18 src/lspst.c --- a/src/lspst.c Sat Jun 06 13:53:34 2009 -0700 +++ b/src/lspst.c Mon Jun 08 11:49:39 2009 -0700 @@ -47,6 +47,8 @@ { struct file_ll ff; pst_item *item = NULL; + char *result = NULL; + size_t resultlen = 0; DEBUG_ENT("process"); memset(&ff, 0, sizeof(ff)); @@ -82,7 +84,7 @@ } printf("Contact"); if (item->contact->fullname.str) - printf("\t%s", pst_rfc2426_escape(item->contact->fullname.str)); + printf("\t%s", pst_rfc2426_escape(item->contact->fullname.str, &result, &resultlen)); printf("\n"); } else if (item->email && ((item->type == PST_TYPE_NOTE) || (item->type == PST_TYPE_SCHEDULE) || (item->type == PST_TYPE_REPORT))) { @@ -105,7 +107,7 @@ DEBUG_INFO(("I have a journal entry, but folder isn't specified as a journal type. Processing...\n")); } if (item->subject.str) - printf("Journal\t%s\n", pst_rfc2426_escape(item->subject.str)); + printf("Journal\t%s\n", pst_rfc2426_escape(item->subject.str, &result, &resultlen)); } else if (item->appointment && (item->type == PST_TYPE_APPOINTMENT)) { char time_buffer[30]; @@ -117,7 +119,7 @@ } printf("Appointment"); if (item->subject.str) - printf("\tSUMMARY: %s", pst_rfc2426_escape(item->subject.str)); + printf("\tSUMMARY: %s", pst_rfc2426_escape(item->subject.str, &result, &resultlen)); if (item->appointment->start) printf("\tSTART: %s", pst_rfc2445_datetime_format(item->appointment->start, sizeof(time_buffer), time_buffer)); if (item->appointment->end) @@ -139,6 +141,7 @@ } } close_enter_dir(&ff); + if (result) free(result); DEBUG_RET(); } diff -r 2d1111fd70cf -r 94bde95d7e18 src/readpst.c --- a/src/readpst.c Sat Jun 06 13:53:34 2009 -0700 +++ b/src/readpst.c Mon Jun 08 11:49:39 2009 -0700 @@ -1218,7 +1218,8 @@ char boundary[60]; char altboundary[66]; char *altboundaryp = NULL; - char body_charset[60]; + char body_charset[30]; + char buffer_charset[30]; char body_report[60]; char sender[60]; int sender_known = 0; @@ -1234,7 +1235,7 @@ headers = (item->email->header.str) ? item->email->header.str : *extra_mime_headers; // setup default body character set and report type - strncpy(body_charset, pst_default_charset(item), sizeof(body_charset)); + strncpy(body_charset, pst_default_charset(item, sizeof(buffer_charset), buffer_charset), sizeof(body_charset)); body_charset[sizeof(body_charset)-1] = '\0'; body_report[0] = '\0'; @@ -1506,9 +1507,11 @@ } -void write_vcard(FILE* f_output, pst_item *item, pst_item_contact* contact, char comment[]) +void write_vcard(FILE* f_output, pst_item* item, pst_item_contact* contact, char comment[]) { - char time_buffer[30]; + char* result = NULL; + size_t resultlen = 0; + char time_buffer[30]; // 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. @@ -1570,96 +1573,99 @@ // 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.str)); + fprintf(f_output, "FN:%s\n", pst_rfc2426_escape(contact->fullname.str, &result, &resultlen)); //fprintf(f_output, "N:%s;%s;%s;%s;%s\n", - 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)); + fprintf(f_output, "N:%s;", (!contact->surname.str) ? "" : pst_rfc2426_escape(contact->surname.str, &result, &resultlen)); + fprintf(f_output, "%s;", (!contact->first_name.str) ? "" : pst_rfc2426_escape(contact->first_name.str, &result, &resultlen)); + fprintf(f_output, "%s;", (!contact->middle_name.str) ? "" : pst_rfc2426_escape(contact->middle_name.str, &result, &resultlen)); + fprintf(f_output, "%s;", (!contact->display_name_prefix.str) ? "" : pst_rfc2426_escape(contact->display_name_prefix.str, &result, &resultlen)); + fprintf(f_output, "%s\n", (!contact->suffix.str) ? "" : pst_rfc2426_escape(contact->suffix.str, &result, &resultlen)); if (contact->nickname.str) - fprintf(f_output, "NICKNAME:%s\n", pst_rfc2426_escape(contact->nickname.str)); + fprintf(f_output, "NICKNAME:%s\n", pst_rfc2426_escape(contact->nickname.str, &result, &resultlen)); if (contact->address1.str) - fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address1.str)); + fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address1.str, &result, &resultlen)); if (contact->address2.str) - fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address2.str)); + fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address2.str, &result, &resultlen)); if (contact->address3.str) - fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address3.str)); + fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address3.str, &result, &resultlen)); if (contact->birthday) fprintf(f_output, "BDAY:%s\n", pst_rfc2425_datetime_format(contact->birthday, sizeof(time_buffer), time_buffer)); 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.str) ? "" : pst_rfc2426_escape(contact->home_po_box.str)); + fprintf(f_output, "ADR;TYPE=home:%s;", (!contact->home_po_box.str) ? "" : pst_rfc2426_escape(contact->home_po_box.str, &result, &resultlen)); fprintf(f_output, "%s;", ""); // extended 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)); + fprintf(f_output, "%s;", (!contact->home_street.str) ? "" : pst_rfc2426_escape(contact->home_street.str, &result, &resultlen)); + fprintf(f_output, "%s;", (!contact->home_city.str) ? "" : pst_rfc2426_escape(contact->home_city.str, &result, &resultlen)); + fprintf(f_output, "%s;", (!contact->home_state.str) ? "" : pst_rfc2426_escape(contact->home_state.str, &result, &resultlen)); + fprintf(f_output, "%s;", (!contact->home_postal_code.str) ? "" : pst_rfc2426_escape(contact->home_postal_code.str, &result, &resultlen)); + fprintf(f_output, "%s\n", (!contact->home_country.str) ? "" : pst_rfc2426_escape(contact->home_country.str, &result, &resultlen)); + fprintf(f_output, "LABEL;TYPE=home:%s\n", pst_rfc2426_escape(contact->home_address.str, &result, &resultlen)); } 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.str) ? "" : pst_rfc2426_escape(contact->business_po_box.str)); + fprintf(f_output, "ADR;TYPE=work:%s;", (!contact->business_po_box.str) ? "" : pst_rfc2426_escape(contact->business_po_box.str, &result, &resultlen)); fprintf(f_output, "%s;", ""); // extended 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)); + fprintf(f_output, "%s;", (!contact->business_street.str) ? "" : pst_rfc2426_escape(contact->business_street.str, &result, &resultlen)); + fprintf(f_output, "%s;", (!contact->business_city.str) ? "" : pst_rfc2426_escape(contact->business_city.str, &result, &resultlen)); + fprintf(f_output, "%s;", (!contact->business_state.str) ? "" : pst_rfc2426_escape(contact->business_state.str, &result, &resultlen)); + fprintf(f_output, "%s;", (!contact->business_postal_code.str) ? "" : pst_rfc2426_escape(contact->business_postal_code.str, &result, &resultlen)); + fprintf(f_output, "%s\n", (!contact->business_country.str) ? "" : pst_rfc2426_escape(contact->business_country.str, &result, &resultlen)); + fprintf(f_output, "LABEL;TYPE=work:%s\n", pst_rfc2426_escape(contact->business_address.str, &result, &resultlen)); } 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.str) ? "" : pst_rfc2426_escape(contact->other_po_box.str)); + fprintf(f_output, "ADR;TYPE=postal:%s;",(!contact->other_po_box.str) ? "" : pst_rfc2426_escape(contact->other_po_box.str, &result, &resultlen)); fprintf(f_output, "%s;", ""); // extended 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)); + fprintf(f_output, "%s;", (!contact->other_street.str) ? "" : pst_rfc2426_escape(contact->other_street.str, &result, &resultlen)); + fprintf(f_output, "%s;", (!contact->other_city.str) ? "" : pst_rfc2426_escape(contact->other_city.str, &result, &resultlen)); + fprintf(f_output, "%s;", (!contact->other_state.str) ? "" : pst_rfc2426_escape(contact->other_state.str, &result, &resultlen)); + fprintf(f_output, "%s;", (!contact->other_postal_code.str) ? "" : pst_rfc2426_escape(contact->other_postal_code.str, &result, &resultlen)); + fprintf(f_output, "%s\n", (!contact->other_country.str) ? "" : pst_rfc2426_escape(contact->other_country.str, &result, &resultlen)); + fprintf(f_output, "LABEL;TYPE=postal:%s\n", pst_rfc2426_escape(contact->other_address.str, &result, &resultlen)); } - 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->business_fax.str) fprintf(f_output, "TEL;TYPE=work,fax:%s\n", pst_rfc2426_escape(contact->business_fax.str, &result, &resultlen)); + if (contact->business_phone.str) fprintf(f_output, "TEL;TYPE=work,voice:%s\n", pst_rfc2426_escape(contact->business_phone.str, &result, &resultlen)); + if (contact->business_phone2.str) fprintf(f_output, "TEL;TYPE=work,voice:%s\n", pst_rfc2426_escape(contact->business_phone2.str, &result, &resultlen)); + if (contact->car_phone.str) fprintf(f_output, "TEL;TYPE=car,voice:%s\n", pst_rfc2426_escape(contact->car_phone.str, &result, &resultlen)); + if (contact->home_fax.str) fprintf(f_output, "TEL;TYPE=home,fax:%s\n", pst_rfc2426_escape(contact->home_fax.str, &result, &resultlen)); + if (contact->home_phone.str) fprintf(f_output, "TEL;TYPE=home,voice:%s\n", pst_rfc2426_escape(contact->home_phone.str, &result, &resultlen)); + if (contact->home_phone2.str) fprintf(f_output, "TEL;TYPE=home,voice:%s\n", pst_rfc2426_escape(contact->home_phone2.str, &result, &resultlen)); + if (contact->isdn_phone.str) fprintf(f_output, "TEL;TYPE=isdn:%s\n", pst_rfc2426_escape(contact->isdn_phone.str, &result, &resultlen)); + if (contact->mobile_phone.str) fprintf(f_output, "TEL;TYPE=cell,voice:%s\n", pst_rfc2426_escape(contact->mobile_phone.str, &result, &resultlen)); + if (contact->other_phone.str) fprintf(f_output, "TEL;TYPE=msg:%s\n", pst_rfc2426_escape(contact->other_phone.str, &result, &resultlen)); + if (contact->pager_phone.str) fprintf(f_output, "TEL;TYPE=pager:%s\n", pst_rfc2426_escape(contact->pager_phone.str, &result, &resultlen)); + if (contact->primary_fax.str) fprintf(f_output, "TEL;TYPE=fax,pref:%s\n", pst_rfc2426_escape(contact->primary_fax.str, &result, &resultlen)); + if (contact->primary_phone.str) fprintf(f_output, "TEL;TYPE=phone,pref:%s\n", pst_rfc2426_escape(contact->primary_phone.str, &result, &resultlen)); + if (contact->radio_phone.str) fprintf(f_output, "TEL;TYPE=pcs:%s\n", pst_rfc2426_escape(contact->radio_phone.str, &result, &resultlen)); + if (contact->telex.str) fprintf(f_output, "TEL;TYPE=bbs:%s\n", pst_rfc2426_escape(contact->telex.str, &result, &resultlen)); + if (contact->job_title.str) fprintf(f_output, "TITLE:%s\n", pst_rfc2426_escape(contact->job_title.str, &result, &resultlen)); + if (contact->profession.str) fprintf(f_output, "ROLE:%s\n", pst_rfc2426_escape(contact->profession.str, &result, &resultlen)); if (contact->assistant_name.str || contact->assistant_phone.str) { fprintf(f_output, "AGENT:BEGIN:VCARD\n"); - 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->assistant_name.str) fprintf(f_output, "FN:%s\n", pst_rfc2426_escape(contact->assistant_name.str, &result, &resultlen)); + if (contact->assistant_phone.str) fprintf(f_output, "TEL:%s\n", pst_rfc2426_escape(contact->assistant_phone.str, &result, &resultlen)); } - 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)); + if (contact->company_name.str) fprintf(f_output, "ORG:%s\n", pst_rfc2426_escape(contact->company_name.str, &result, &resultlen)); + if (comment) fprintf(f_output, "NOTE:%s\n", pst_rfc2426_escape(comment, &result, &resultlen)); fprintf(f_output, "VERSION: 3.0\n"); fprintf(f_output, "END:VCARD\n\n"); + if (result) free(result); DEBUG_RET(); } void write_journal(FILE* f_output, pst_item* item) { - char time_buffer[30]; + char* result = NULL; + size_t resultlen = 0; + char time_buffer[30]; pst_item_journal* journal = item->journal; // make everything utf8 @@ -1673,18 +1679,21 @@ if (item->modify_date) fprintf(f_output, "LAST-MOD:%s\n", pst_rfc2445_datetime_format(item->modify_date, sizeof(time_buffer), time_buffer)); if (item->subject.str) - fprintf(f_output, "SUMMARY:%s\n", pst_rfc2426_escape(item->subject.str)); + fprintf(f_output, "SUMMARY:%s\n", pst_rfc2426_escape(item->subject.str, &result, &resultlen)); if (item->body.str) - fprintf(f_output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->body.str)); + fprintf(f_output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->body.str, &result, &resultlen)); if (journal && journal->start) fprintf(f_output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(journal->start, sizeof(time_buffer), time_buffer)); fprintf(f_output, "END:VJOURNAL\n"); + if (result) free(result); } void write_appointment(FILE* f_output, pst_item* item, int event_open) { - char time_buffer[30]; + char* result = NULL; + size_t resultlen = 0; + char time_buffer[30]; pst_item_appointment* appointment = item->appointment; // make everything utf8 @@ -1699,15 +1708,15 @@ if (item->modify_date) fprintf(f_output, "LAST-MOD:%s\n", pst_rfc2445_datetime_format(item->modify_date, sizeof(time_buffer), time_buffer)); if (item->subject.str) - fprintf(f_output, "SUMMARY:%s\n", pst_rfc2426_escape(item->subject.str)); + fprintf(f_output, "SUMMARY:%s\n", pst_rfc2426_escape(item->subject.str, &result, &resultlen)); if (item->body.str) - fprintf(f_output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->body.str)); + fprintf(f_output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->body.str, &result, &resultlen)); if (appointment && appointment->start) fprintf(f_output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(appointment->start, sizeof(time_buffer), time_buffer)); if (appointment && appointment->end) fprintf(f_output, "DTEND;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(appointment->end, sizeof(time_buffer), time_buffer)); if (appointment && appointment->location.str) - fprintf(f_output, "LOCATION:%s\n", pst_rfc2426_escape(appointment->location.str)); + fprintf(f_output, "LOCATION:%s\n", pst_rfc2426_escape(appointment->location.str, &result, &resultlen)); if (appointment) { switch (appointment->showas) { case PST_FREEBUSY_TENTATIVE: @@ -1788,6 +1797,7 @@ } } fprintf(f_output, "END:VEVENT\n"); + if (result) free(result); }