The attached patch is an extension to the earlier patch from
http://mailman.openchange.org/pipermail/devel/2011-March/005356.html
It includes the export of the e-mail addresses in the distribution
lists. It can be tested with this command:
bin/openchangeclient --pf --fetch-items=Contact --folder <FOLDERNAME>
I looked also at the issue of character encoding, because the e-mail
addresses of distribution lists are available only in UTF16.
So far I'm using only a poor man converter, which should be fine as far
as e-mail addresses use ASCII codes only.
The conversion from PT_STRING8 to UTF8 is also still open. Which
conversion function are you typically using ?
*_to_utf8 functions are provided by a number of libraries:
glib
ldap
GNU Libidn/stringprep
raptor
rdf_utf8
ldap_utf8.h
mono-1.0/mono/metadata/object.h:mono_string_to_utf8
Which libraries should be used preferably within openchange ?
Kind regards,
Alois
Index: libmapi/mapidump.c
===================================================================
--- libmapi/mapidump.c (revision 2748)
+++ libmapi/mapidump.c (working copy)
@@ -2,6 +2,7 @@
OpenChange MAPI implementation.
Copyright (C) Julien Kerihuel 2007-2011.
+ Copyright (C) Alois Schloegl, IST Austria, 2011.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -548,7 +549,9 @@
const char *given_name = NULL;
const char *surname = NULL;
const char *company = NULL;
- const char *email = NULL;
+ const char *email1 = NULL;
+ const char *email2 = NULL;
+ const char *email3 = NULL;
const char *title = NULL;
const char *office_phone = NULL;
const char *home_phone = NULL;
@@ -561,6 +564,7 @@
const char *department = NULL;
const char *business_fax = NULL;
const char *business_home_page = NULL;
+ const char *distribution_list = NULL;
card_name = (const char *)find_mapi_SPropValue_data(properties, PidLidFileUnder);
topic = (const char *)find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC);
@@ -570,7 +574,52 @@
given_name = (const char *)find_mapi_SPropValue_data(properties, PR_GIVEN_NAME);
surname = (const char *)find_mapi_SPropValue_data(properties, PR_SURNAME);
department = (const char *)find_mapi_SPropValue_data(properties, PR_DEPARTMENT_NAME);
- email = (const char *)find_mapi_SPropValue_data(properties, PidLidEmail1OriginalDisplayName);
+
+// these definitions should go somewhere else; perhaps ./libmapi/property_altnames.h but is built by script/makepropslist.py
+#define PR_EMAIL1_DISPLAY_NAME PROP_TAG(PT_STRING8 , 0x8080) /* 0x8080001E */
+#define PR_EMAIL1_EMAIL_ADDDESS PROP_TAG(PT_STRING8 , 0x8083) /* 0x8083001E */
+#define PR_EMAIL1_ORIGINAL_DISPLAY_NAME PROP_TAG(PT_STRING8 , 0x8084) /* 0x8084001E */
+#define PR_EMAIL2_DISPLAY_NAME PROP_TAG(PT_STRING8 , 0x8090) /* 0x9080001E */
+#define PR_EMAIL2_EMAIL_ADDRESS PROP_TAG(PT_STRING8 , 0x8093) /* 0x9083001E */
+#define PR_EMAIL2_ORIGINAL_DISPLAY_NAME PROP_TAG(PT_STRING8 , 0x8094) /* 0x9084001E */
+#define PR_EMAIL3_DISPLAY_NAME PROP_TAG(PT_STRING8 , 0x80A0) /* 0xA080001E */
+#define PR_EMAIL3_EMAIL_ADDRESS PROP_TAG(PT_STRING8 , 0x80A3) /* 0xA083001E */
+#define PR_EMAIL3_ORIGINAL_DISPLAY_NAME PROP_TAG(PT_STRING8 , 0x80A4) /* 0xA084001E */
+
+#define PR_EMAIL1_DISPLAY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x8080) /* 0x8080001F */
+#define PR_EMAIL1_EMAIL_ADDDESS_UNICODE PROP_TAG(PT_UNICODE , 0x8083) /* 0x8083001F */
+#define PR_EMAIL1_ORIGINAL_DISPLAY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x8084) /* 0x8084001F */
+#define PR_EMAIL2_DISPLAY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x8090) /* 0x9080001F */
+#define PR_EMAIL2_EMAIL_ADDRESS_UNICODE PROP_TAG(PT_UNICODE , 0x8093) /* 0x9083001F */
+#define PR_EMAIL2_ORIGINAL_DISPLAY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x8094) /* 0x9084001F */
+#define PR_EMAIL3_DISPLAY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x80A0) /* 0xA080001F */
+#define PR_EMAIL3_EMAIL_ADDRESS_UNICODE PROP_TAG(PT_UNICODE , 0x80A3) /* 0xA083001F */
+#define PR_EMAIL3_ORIGINAL_DISPLAY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x80A4) /* 0xA084001F */
+
+#define PR_DISTRIBUTION_LIST_NAME PROP_TAG(PT_STRING8 , 0x8053) /* 0x8053001E */
+ distribution_list = (const char *)find_mapi_SPropValue_data(properties, PR_DISTRIBUTION_LIST_NAME);
+
+ if (!email1) email1 = (const char *)find_mapi_SPropValue_data(properties, PR_EMAIL1_DISPLAY_NAME);
+ if (email1 && !strchr(email1,'@')) email1 = NULL;
+ if (!email1) email1 = (const char *)find_mapi_SPropValue_data(properties, PR_EMAIL1_EMAIL_ADDDESS);
+ if (email1 &&!strchr(email1,'@')) email1 = NULL;
+ if (!email1) email1 = (const char *)find_mapi_SPropValue_data(properties, PR_EMAIL1_ORIGINAL_DISPLAY_NAME);
+ if (email1 &&!strchr(email1,'@')) email1 = NULL;
+
+ if (!email2) email2 = (const char *)find_mapi_SPropValue_data(properties, PR_EMAIL2_DISPLAY_NAME);
+ if (email2 && !strchr(email2,'@')) email2 = NULL;
+ if (!email2) email2 = (const char *)find_mapi_SPropValue_data(properties, PR_EMAIL2_EMAIL_ADDRESS);
+ if (email2 && !strchr(email2,'@')) email2 = NULL;
+ if (!email2) email2 = (const char *)find_mapi_SPropValue_data(properties, PR_EMAIL2_ORIGINAL_DISPLAY_NAME);
+ if (email2 && !strchr(email2,'@')) email2 = NULL;
+
+ if (!email3) email3 = (const char *)find_mapi_SPropValue_data(properties, PR_EMAIL3_DISPLAY_NAME);
+ if (email3 && !strchr(email3,'@')) email3 = NULL;
+ if (!email3) email3 = (const char *)find_mapi_SPropValue_data(properties, PR_EMAIL3_EMAIL_ADDRESS);
+ if (email3 && !strchr(email3,'@')) email3 = NULL;
+ if (!email3) email3 = (const char *)find_mapi_SPropValue_data(properties, PR_EMAIL3_ORIGINAL_DISPLAY_NAME);
+ if (email3 && !strchr(email3,'@')) email3 = NULL;
+
office_phone = (const char *)find_mapi_SPropValue_data(properties, PR_OFFICE_TELEPHONE_NUMBER);
home_phone = (const char *)find_mapi_SPropValue_data(properties, PR_HOME_TELEPHONE_NUMBER);
mobile_phone = (const char *)find_mapi_SPropValue_data(properties, PR_MOBILE_TELEPHONE_NUMBER);
@@ -591,6 +640,7 @@
fflush(0);
if (topic) printf("Topic: %s\n", topic);
fflush(0);
+
if (full_name)
printf("Full Name: %s\n", full_name);
else if (given_name && surname)
@@ -602,8 +652,79 @@
fflush(0);
if (company) printf("Company: %s\n", company);
fflush(0);
- if (email) printf("E-mail: %s\n", email);
+
+ if (distribution_list) {
+ printf("Distribution List: %s\nE-mail: ", distribution_list);
+
+ struct mapi_SBinaryArray *ptr;
+ ptr = (struct mapi_SBinaryArray*) find_mapi_SPropValue_data(properties, PidLidDistributionListOneOffMembers);
+
+ int k;
+ for (k=0; k < ptr->cValues; k++) {
+ struct SBinary_short SBinS = ptr->bin[k];
+ uint16_t cb16 = SBinS.cb; // length
+
+ char *s0,*s1,*s2;
+ char buf[1500];
+
+ // decode OneOff EntryId's [MS-OXCDATA] -- v20101026: section 2.2.5.1 One-Off EntryID
+ if (SBinS.lpb[23] & 0x80) {
+ // Unicode (UTF16)
+ // FIXME: poor man's conversion from ucs2/utf16??? format - extract just every 2nd byte
+ // Because only the email address is of interest (ASCII only), this should be fine.
+ // Alternative: glib has a function g_utf16_to_utf8: do we want a dependency on glib ?
+ int m;
+ for (m=0; m < (cb16-24)/2; m++) buf[m] = SBinS.lpb[24+m*2];
+ s0 = buf;
+ }
+ else {
+ // Multibyte character set (MBCS)
+ s0 = SBinS.lpb+24;
+ }
+
+ // s0 contains 3 consecutive, \0-terminated strings, the third contains the e-mail address.
+ s1 = s0 + strlen(s0) + 1;
+ s2 = s1 + strlen(s1) + 1;
+ if (k) printf(", ");
+ printf("%s",s2);
+ }
+ printf("\n\n");
+ fflush(0);
+ return;
+ }
+
+ // convert to unix style e-mail addresses "Fffff Nnnnnn ([email protected])" to "Fffff Nnnnn <[email protected]>"
+ int i;
+ char *tmpemail = NULL;
+ if (email1) {
+ tmpemail = realloc(tmpemail,strlen(email1)+1);
+ strcpy(tmpemail,email1);
+ for (i=0; i<strlen(tmpemail); i++)
+ if (tmpemail[i]=='(') tmpemail[i]='<';
+ else if (tmpemail[i]==')') tmpemail[i]='>';
+ printf("E-mail1: %s\n", tmpemail);
+ }
fflush(0);
+ if (email2) {
+ tmpemail = realloc(tmpemail,strlen(email2)+1);
+ strcpy(tmpemail,email2);
+ for (i=0; i<strlen(tmpemail); i++)
+ if (tmpemail[i]=='(') tmpemail[i]='<';
+ else if (tmpemail[i]==')') tmpemail[i]='>';
+ printf("E-mail2: %s\n", tmpemail);
+ }
+ fflush(0);
+ if (email3) {
+ tmpemail = realloc(tmpemail,strlen(email3)+1);
+ strcpy(tmpemail,email3);
+ for (i=0; i<strlen(tmpemail); i++)
+ if (tmpemail[i]=='(') tmpemail[i]='<';
+ else if (tmpemail[i]==')') tmpemail[i]='>';
+ printf("E-mail3: %s\n", tmpemail);
+ }
+ if (tmpemail) free(tmpemail);
+ fflush(0);
+
if (office_phone) printf("Office phone number: %s\n", office_phone);
fflush(0);
if (home_phone) printf("Work phone number: %s\n", home_phone);
_______________________________________________
devel mailing list
[email protected]
http://mailman.openchange.org/listinfo/devel