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

Reply via email to