On 09/29/11 11:43, Brad Hards wrote:
On Thursday 29 September 2011 19:37:38 Alois Schloegl wrote:
It seems that there is a synchronization issue, when the server is
internally updating and openchange tries to read the data from the
server at the same time.
That seems unlikely - there is quite sophisticated locking on the Exchange
database side. Its not impossible though.

This raises the following questions:
1) Are You aware of this issue ?
I am personally not.

2) I'm using the above test to check for the consistency of the result.
Is there are better solution or workaround for this problem ?
I don't really understand what you're seeing, so I can't advise further.


Here is a more detailed explanation. The "contacts" in public folder of an exchange server are exported with openchangeclient (*), using

openchangeclient --pf --fetch-items=Contact --folder "Contacts"> testocx.txt

The first two data sets of the resulting file are attached (**). First line in file testocx.txt (i.e. "MAILBOX (1586 messages)" contains the number of exported data sets. (The term MAILBOX is misleading, but irrelevant)

Then, one gets the individual data sets, each starting with
   |== <CARD_NAME> ==| : <ID>

Usually, the number indicated in the first line "MAILBOX (1586 messages)" matches the number of lines in
   grep '^|==.*==| : ' testocx.txt

However, these numbers do frequently not match, indicating that something went wrong with the export. The attached perl script (***) shows the problem. It gives a warning like this
$ cat doc/testocx.txt |test/test_oc2db.pl
Warning OC2DB: number of records do not match ( 2 != 1586 )

In summary, the following command demonstrate the issue (*4):
openchangeclient --pf --fetch-items=Contact --folder "your_contacts" | test_oc2db.pl

I hope this makes the issue more clear.
  Alois



(*) patch_unicode+keywords.diff: the function function mapidump_contact in libmapi/mapidump.c is actually patched, it incorporates a field separator 0x1e, in order to avoid escaping of special characters within each field.

(**) The field separator ASCII(0x1e) introduced by the patch has
been removed with tr -d '\036' <testocx.txt

(***) this is an excerpt of a larger script of exporting the data into an SQL database. If anyone is interested in this, I can provide the full script.

(*4) If you have applied the patch (*), then the redefinition of line breaks in test_oc2db.pl is needed (line 31: $/ = "\n\x1e";).




Index: libmapi/mapidump.c
===================================================================
--- libmapi/mapidump.c	(revision 3211)
+++ 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
@@ -20,6 +21,7 @@
 #include "libmapi/libmapi.h"
 #include "libmapi/libmapi_private.h"
 #include "libmapi/mapidump.h"
+#include <iconv.h>
 #include <time.h>
 
 #ifdef ENABLE_ASSERTS
@@ -556,16 +558,21 @@
 {
 	const char	*card_name =NULL;
 	const char	*topic =NULL;
+	const char 	*fileas = NULL;
 	const char	*full_name = NULL;
 	const char	*given_name = NULL;
+	const char	*middle_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;
 	const char      *mobile_phone = NULL;
 	const char      *postal_address = NULL;
+	const char      *postal_code = NULL;
 	const char      *street_address = NULL;
 	const char      *locality = NULL;
 	const char      *state = NULL;
@@ -573,73 +580,410 @@
 	const char      *department = NULL;
 	const char      *business_fax = NULL;
 	const char      *business_home_page = NULL;
+	const char 	*distribution_list = NULL;
+	struct mapi_SLPSTRArrayW *keywords = NULL;
+        const char      *keyword = NULL; 
+        const char      *initials = NULL; 
+        const char      *name_prefix = NULL; 
+        const char      *profession = NULL; 
+        void            *birthday = NULL;	//PtypTime 0x40
+        uint16_t  	gender = 0; 
+        uint32_t	fileasId = 0;
 
+	size_t buflen = 300;       	                        
+      	char buf[buflen + 1];
+
 	card_name = (const char *)find_mapi_SPropValue_data(properties, PidLidFileUnder);
-	topic = (const char *)find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC);
-	company = (const char *)find_mapi_SPropValue_data(properties, PR_COMPANY_NAME);
-	title = (const char *)find_mapi_SPropValue_data(properties, PR_TITLE);
-	full_name = (const char *)find_mapi_SPropValue_data(properties, PR_DISPLAY_NAME);
-	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);
-	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);
-	business_fax = (const char *)find_mapi_SPropValue_data(properties, PR_BUSINESS_FAX_NUMBER);
-	business_home_page = (const char *)find_mapi_SPropValue_data(properties, PR_BUSINESS_HOME_PAGE);
-	postal_address = (const char*)find_mapi_SPropValue_data(properties, PR_POSTAL_ADDRESS);
-	street_address = (const char*)find_mapi_SPropValue_data(properties, PR_STREET_ADDRESS);
-	locality = (const char*)find_mapi_SPropValue_data(properties, PR_LOCALITY);
-	state = (const char*)find_mapi_SPropValue_data(properties, PR_STATE_OR_PROVINCE);
-	country = (const char*)find_mapi_SPropValue_data(properties, PR_COUNTRY);
+	topic     = (const char *)find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC_UNICODE);
+	fileas    = (const char*) find_mapi_SPropValue_data(properties, PidNameContactsFileAs-1);
+	fileasId  = *(uint32_t*) find_mapi_SPropValue_data(properties, PidNameContactsFileasId);
+	company   = (const char *)find_mapi_SPropValue_data(properties, PR_COMPANY_NAME_UNICODE);
+	title     = (const char *)find_mapi_SPropValue_data(properties, PR_TITLE_UNICODE);
+	full_name = (const char *)find_mapi_SPropValue_data(properties, PR_DISPLAY_NAME_UNICODE);
+	given_name = (const char *)find_mapi_SPropValue_data(properties, PR_GIVEN_NAME_UNICODE);
+	middle_name = (const char *)find_mapi_SPropValue_data(properties, PR_MIDDLE_NAME_UNICODE);
+	surname   = (const char *)find_mapi_SPropValue_data(properties, PR_SURNAME_UNICODE);
+	department = (const char *)find_mapi_SPropValue_data(properties, PR_DEPARTMENT_NAME_UNICODE);
+	office_phone = (const char *)find_mapi_SPropValue_data(properties, PR_OFFICE_TELEPHONE_NUMBER_UNICODE);
+	home_phone = (const char *)find_mapi_SPropValue_data(properties, PR_HOME_TELEPHONE_NUMBER_UNICODE);
+	mobile_phone = (const char *)find_mapi_SPropValue_data(properties, PR_MOBILE_TELEPHONE_NUMBER_UNICODE);
+	business_fax = (const char *)find_mapi_SPropValue_data(properties, PR_BUSINESS_FAX_NUMBER_UNICODE);
+	business_home_page = (const char *)find_mapi_SPropValue_data(properties, PR_BUSINESS_HOME_PAGE_UNICODE);
+	postal_address = (const char*)find_mapi_SPropValue_data(properties, PR_POSTAL_ADDRESS_UNICODE);
+	postal_code = (const char*)find_mapi_SPropValue_data(properties, PR_POSTAL_CODE_UNICODE);
+	street_address = (const char*)find_mapi_SPropValue_data(properties, PR_STREET_ADDRESS_UNICODE);
+	locality = (const char*)find_mapi_SPropValue_data(properties, PR_LOCALITY_UNICODE);
+	state    = (const char*)find_mapi_SPropValue_data(properties, PR_STATE_OR_PROVINCE_UNICODE);
+	country  = (const char*)find_mapi_SPropValue_data(properties, PR_COUNTRY_UNICODE);
+//        keyword  = (const char*)find_mapi_SPropValue_data(properties, PR_KEYWORD_UNICODE);
 
+        initials = (const char*)find_mapi_SPropValue_data(properties, PR_INITIALS_UNICODE);
+        name_prefix = (const char*)find_mapi_SPropValue_data(properties, PR_DISPLAY_NAME_PREFIX_UNICODE);
+        profession = (const char*)find_mapi_SPropValue_data(properties, PR_PROFESSION_UNICODE);
+        birthday = (void *)find_mapi_SPropValue_data(properties, PR_BIRTHDAY);
+//        birthday = (void *)find_mapi_SPropValue_data(properties, PidTagBirthday);
+//        gender = *(uint16_t*)find_mapi_SPropValue_data(properties, PidTagGender);
+                                        
+	if (!topic) 		topic = (const char *)find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC);
+	if (!company) 		company = (const char *)find_mapi_SPropValue_data(properties, PR_COMPANY_NAME);
+	if (!title) 		title = (const char *)find_mapi_SPropValue_data(properties, PR_TITLE);
+	if (!full_name) 	full_name = (const char *)find_mapi_SPropValue_data(properties, PR_DISPLAY_NAME);
+	if (!given_name) 	given_name = (const char *)find_mapi_SPropValue_data(properties, PR_GIVEN_NAME);
+	if (!middle_name) 	middle_name = (const char *)find_mapi_SPropValue_data(properties, PR_MIDDLE_NAME);
+	if (!surname)  		surname = (const char *)find_mapi_SPropValue_data(properties, PR_SURNAME);
+	if (!department) 	department = (const char *)find_mapi_SPropValue_data(properties, PR_DEPARTMENT_NAME);
+	if (!office_phone)      office_phone = (const char *)find_mapi_SPropValue_data(properties, PR_OFFICE_TELEPHONE_NUMBER);
+	if (!home_phone)        home_phone = (const char *)find_mapi_SPropValue_data(properties, PR_HOME_TELEPHONE_NUMBER);
+	if (!mobile_phone)      mobile_phone = (const char *)find_mapi_SPropValue_data(properties, PR_MOBILE_TELEPHONE_NUMBER);
+	if (!business_fax)      business_fax = (const char *)find_mapi_SPropValue_data(properties, PR_BUSINESS_FAX_NUMBER);
+	if (!business_home_page) business_home_page = (const char *)find_mapi_SPropValue_data(properties, PR_BUSINESS_HOME_PAGE);
+	if (!postal_address)    postal_address = (const char*)find_mapi_SPropValue_data(properties, PR_POSTAL_ADDRESS);
+	if (!postal_code)    postal_address = (const char*)find_mapi_SPropValue_data(properties, PR_POSTAL_CODE);
+	if (!street_address)    street_address = (const char*)find_mapi_SPropValue_data(properties, PR_STREET_ADDRESS);
+	if (!locality)          locality = (const char*)find_mapi_SPropValue_data(properties, PR_LOCALITY);
+	if (!state)             state = (const char*)find_mapi_SPropValue_data(properties, PR_STATE_OR_PROVINCE);
+	if (!country)           country = (const char*)find_mapi_SPropValue_data(properties, PR_COUNTRY);
+        if (!keyword)           keyword = (const char*)find_mapi_SPropValue_data(properties, PR_KEYWORD);
+        if (!initials)          initials = (const char*)find_mapi_SPropValue_data(properties, PR_INITIALS);
+        if (!name_prefix)       name_prefix = (const char*)find_mapi_SPropValue_data(properties, PR_DISPLAY_NAME_PREFIX);
+        if (!profession)        profession = (const char*)find_mapi_SPropValue_data(properties, PR_PROFESSION);
+//        if (!gender)             gender = *(uint16_t*)find_mapi_SPropValue_data(properties, PR_GENDER);
+//        if (!keyword)           keyword = (const char*)find_mapi_SPropValue_data(properties, PR_KEYWORD);
+
+// these definitions should go somewhere else; perhaps ./libmapi/property_altnames.h but is built by script/makepropslist.py
+#if 0
+#define PR_EMAIL1_DISPLAY_NAME                                               PROP_TAG(PT_STRING8   , 0x8080)  /* 0x8080001E */
+#define PR_EMAIL1_EMAIL_ADDRESS                                              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_DISTRIBUTION_LIST_NAME					     PROP_TAG(PT_STRING8   , 0x8053)  /* 0x8053001E */
+#else
+#define PR_EMAIL1_DISPLAY_NAME                                               PROP_TAG(PT_UNICODE   , 0x8080)  /* 0x8080001F */
+#define PR_EMAIL1_EMAIL_ADDRESS                                              PROP_TAG(PT_UNICODE   , 0x8083)  /* 0x8083001F */
+#define PR_EMAIL1_ORIGINAL_DISPLAY_NAME                                      PROP_TAG(PT_UNICODE   , 0x8084)  /* 0x8084001F */
+#define PR_EMAIL2_DISPLAY_NAME                                               PROP_TAG(PT_UNICODE   , 0x8090)  /* 0x9080001F */
+#define PR_EMAIL2_EMAIL_ADDRESS                                              PROP_TAG(PT_UNICODE   , 0x8093)  /* 0x9083001F */
+#define PR_EMAIL2_ORIGINAL_DISPLAY_NAME                                      PROP_TAG(PT_UNICODE   , 0x8094)  /* 0x9084001F */
+#define PR_EMAIL3_DISPLAY_NAME                                               PROP_TAG(PT_UNICODE   , 0x80A0)  /* 0xA080001F */
+#define PR_EMAIL3_EMAIL_ADDRESS                                              PROP_TAG(PT_UNICODE   , 0x80A3)  /* 0xA083001F */
+#define PR_EMAIL3_ORIGINAL_DISPLAY_NAME                                      PROP_TAG(PT_UNICODE   , 0x80A4)  /* 0xA084001F */
+
+#define PR_DISTRIBUTION_LIST_NAME         				     PROP_TAG(PT_UNICODE   , 0x8053)  /* 0x8053001F */
+#endif 
+
+	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_ADDRESS);
+        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; 
+
+
+        if (!keywords) keywords = (struct mapi_SLPSTRArrayW*) find_mapi_SPropValue_data(properties, 0x8025101f);
+/*
+        // not helpful         
+        if (!keywords) keywords = (struct mapi_SLPSTRArrayW*) find_mapi_SPropValue_data(properties, PidNameKeywords);
+        if (!keywords) keywords = (struct mapi_SLPSTRArrayW*) find_mapi_SPropValue_data(properties, PR_KEYWORD_UNICODE);
+*/                
+
+
+// use non-printable character as record separator
+#define RECSEP  "\n\x1e"	
+                
+        printf("%s",RECSEP);        
 	if (card_name) 
-		printf("|== %s ==| %s\n", card_name, id?id:"");
+		printf("|== %s ==| %s%s", card_name, id?id:"", RECSEP);
 	else if (topic)
-		printf("|== %s ==| %s\n", topic, id?id:"");
+		printf("|== %s ==| %s%s", topic, id?id:"", RECSEP);
 	else 
-	  printf("|== <Unknown> ==| %s\n", id?id:"");
+	        printf("|== <Unknown> ==| %s%s", id?id:"", RECSEP);
 	fflush(0);
-	if (topic) printf("Topic: %s\n", topic);
+	if (topic) printf("Topic: %s%s", topic, RECSEP);
 	fflush(0);
-	if (full_name)
-		printf("Full Name: %s\n", full_name);
+	if (topic) printf("Canonical name: %s %s%s", given_name, surname, RECSEP);
+	fflush(0);
+
+	if (full_name) 
+                printf("Full Name: %s%s", full_name, RECSEP);
 	else if (given_name && surname)
-		printf("Full Name: %s %s\n", given_name, surname); // initials? l10n?
+		printf("Full Name: %s %s%s", given_name, surname, RECSEP); // initials? l10n?
+//        if (gender) printf("Gender: %c\n", gender==1 ? 'F' : 'M');
+        if (initials) 	printf("Initials: %s%s",initials, RECSEP);
+        if (name_prefix) printf("Name Prefix: %s%s",name_prefix, RECSEP);
+        if (given_name)  printf("Given Name: %s%s", given_name, RECSEP);
+        if (middle_name && strlen(middle_name)) printf("Middle Name: %s%s", middle_name, RECSEP);
+        if (surname)     printf("Surname: %s%s", surname, RECSEP);
 	fflush(0);
-	if (title) printf("Job Title: %s\n", title);
+	if (title) 	printf("Job Title: %s%s", title, RECSEP);
 	fflush(0);
-	if (department) printf("Department: %s\n", department);
+	if (department) printf("Department: %s%s", department, RECSEP);
 	fflush(0);
-	if (company) printf("Company: %s\n", company);
+	if (company) 	printf("Company: %s%s", company, RECSEP);
 	fflush(0);
-	if (email) printf("E-mail: %s\n", email);
+        if (keyword && strlen(keyword)) printf("Keyword: %s%s", keyword, RECSEP);
+        fflush(0);
+
+        /*
+        	all fields for ldap export start with colon ":" 
+        */
+#define AS_WITH_LDAP 0
+
+#if AS_WITH_LDAP 
+
+        printf(":\n:dn: ch=%s %s,ou=addresses,dc=ist,dc=ac,dc=at\n",given_name,surname);
+        printf(":objectClass: inetOrgPerson\n");
+        printf(":objectClass: person\n");
+        printf(":objectClass: organizationalPerson\n");
+        printf(":objectClass: evolutionPerson\n");
+        printf(":cn: %s %s\n", given_name, surname);
+        printf(":sn: %s\n", surname);
+        if (given_name) printf(":givenName: %s\n", given_name);
+        if (title) printf(":employeeType: %s\n", title);
+        if (department) printf(":ou: %s\n", department);
+        if (company) printf(":o: %s\n", company);
+#endif
+
+
+       	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);
+
+     	        iconv_t utf8_utf16 = iconv_open("UTF8","UTF16");
+        	int k; 
+        	for (k=0; k < ptr->cValues; k++) {
+        	        struct SBinary_short SBinS = ptr->bin[k];
+
+	                char *s0, *s1; 
+                        s0 = SBinS.lpb + 24; 
+
+	                // decode OneOff EntryId's [MS-OXCDATA] -- v20101026: section 2.2.5.1 One-Off EntryID        
+         	        if (SBinS.lpb[23] & 0x80) {
+         	                // Unicode (UTF16) to UTF8 conversion
+                	        size_t s0len = SBinS.cb - 24;
+                	        size_t s1len = buflen;
+                	        s1 = buf; 
+                	        iconv(utf8_utf16, NULL, NULL,  &s1, &s1len);	// initialize iconv
+                	        iconv(utf8_utf16, &s0, &s0len, &s1, &s1len);
+                	        s0 = buf;
+        	        } 
+        	        // else // Multibyte character set (MBCS)
+
+       	                // s0 contains 3 consecutive, \0-terminated strings, the third contains the e-mail address. 
+               	        s1 = strchr(s0,0) + 1;
+                        s1 = strchr(s1,0) + 1;
+	                if (k) printf(", ");
+        	        printf("%s",s1);
+        	}
+        	printf("\n%s", RECSEP);       
+        	fflush(0); 
+     	        iconv_close(utf8_utf16);
+        	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%s", tmpemail, RECSEP);
+#if AS_WITH_LDAP
+	        printf(":mail: %s\n", tmpemail);
+#endif
+	}        
 	fflush(0);
-	if (office_phone) printf("Office phone number: %s\n", office_phone);
+	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%s", tmpemail, RECSEP);
+#if AS_WITH_LDAP
+	        printf(":mail: %s\n", tmpemail);
+#endif
+	}        
 	fflush(0);
-	if (home_phone) printf("Work phone number: %s\n", home_phone);
+	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%s", tmpemail, RECSEP);
+#if AS_WITH_LDAP
+	        printf(":mail: %s\n", tmpemail);
+#endif
+	}        
 	fflush(0);
-	if (mobile_phone) printf("Mobile phone number: %s\n", mobile_phone);
+
+        if (birthday) printf("Birthday:%s", RECSEP);
+        fflush(0);
+	if (office_phone) printf("Office phone number: %s%s", office_phone, RECSEP);
 	fflush(0);
-	if (business_fax) printf("Business fax number: %s\n", business_fax);
+	if (home_phone) printf("Home phone number: %s%s", home_phone, RECSEP);
 	fflush(0);
-	if (business_home_page) printf("Business home page: %s\n", business_home_page);
+	if (mobile_phone) printf("Mobile phone number: %s%s", mobile_phone, RECSEP);
 	fflush(0);
-	if (postal_address) printf("Postal address: %s\n", postal_address);
+	if (business_fax) printf("Business fax number: %s%s", business_fax, RECSEP);
 	fflush(0);
-	if (street_address) printf("Street address: %s\n", street_address);
+	if (business_home_page) printf("Business home page: %s%s", business_home_page, RECSEP);
 	fflush(0);
-	if (locality) printf("Locality: %s\n", locality);
+	if (postal_address) {
+/*
+	        tmpemail = realloc(tmpemail,strlen(postal_address)+1);
+	        strcpy(tmpemail,postal_address);        
+	        // remove trailing blanks
+                i=strlen(tmpemail); while (isspace(tmpemail[i]) && i>=0) tmpemail[i--] = 0; 
+                // replace line breaks with semicolon (and space)
+                for (i=0; i<strlen(tmpemail); i++) {
+                        if (tmpemail[i]==10 || tmpemail[i]==13) {
+                                tmpemail[i++] = ';';
+                                while (tmpemail[i]==10 || tmpemail[i]==13)
+                                        tmpemail[i++] = ' ';
+                        }                        
+                }        
+                printf("Postal address: %s%s", tmpemail, RECSEP);
+*/
+                printf("Postal address: %s%s", postal_address, RECSEP);
+        }        
 	fflush(0);
-	if (state) printf("State / Province: %s\n", state);
+	if (postal_code) {
+                printf("Postal code: %s%s", postal_code, RECSEP);
+        }        
 	fflush(0);
-	if (country) printf("Country: %s\n", country);
+	if (street_address) {
+/*
+	        tmpemail = realloc(tmpemail,strlen(street_address)+1);
+	        strcpy(tmpemail,street_address);        
+	        // remove trailing blanks
+                i=strlen(tmpemail); 
+                while (isspace(tmpemail[i]) && i>=0) tmpemail[i--] = 0; 
+                // replace line breaks with semicolon (and spaces)
+                for (i=0; i<strlen(tmpemail); i++) {
+                        if (tmpemail[i]==10 || tmpemail[i]==13) {
+                                tmpemail[i++] = ';';
+                                while (tmpemail[i]==10 || tmpemail[i]==13)
+                                        tmpemail[i++] = ' ';
+                        }                        
+                }        
+                printf("Street address: %s%s", tmpemail, RECSEP);
+*/
+                printf("Street address: %s%s", street_address, RECSEP);
+	}        
+	if (tmpemail) free(tmpemail); 
 	fflush(0);
+	if (locality) printf("Locality: %s%s", locality, RECSEP);
+	fflush(0);
+	if (state) printf("State / Province: %s%s", state, RECSEP);
+	fflush(0);
+	if (country) printf("Country: %s%s", country, RECSEP);
+	fflush(0);
 
-	printf("\n");
+#if AS_WITH_LDAP
+        if (office_phone && strlen(office_phone) ) printf(":telephoneNumber: %s", office_phone);
+        if (home_phone && strlen(home_phone))   printf(":telephoneNumber: %s\n", home_phone);
+        if (mobile_phone && strlen(mobile_phone) ) printf(":mobile: %s\n", mobile_phone);
+        if (business_fax && strlen(business_fax) ) printf(":facsimilieTelephoneNumber: %s\n", business_fax);
+        if (business_home_page && strlen(business_home_page) ) printf(":labeledURI: %s\n", business_home_page);
+        fflush(0);
+#endif
+
+#if AS_WITH_LDAP
+        if (postal_address && strlen(postal_address)) {
+                strncpy(buf, postal_address, buflen);
+	        int k = 0;
+	        while (k<strlen(buf)) {
+	        	if ( buf[k]==10 || buf[k]==13 ) 
+	        		buf[k] = ' ';	
+	        	k++;	
+	        }
+                printf(":postalAddress: %s\n", buf);	
+		fflush(0);
+	}
+#endif
+#if AS_WITH_LDAP 
+	if (street_address && strlen(street_address)) {
+	        strncpy(buf, street_address, buflen);
+	        int k = 0;
+	        while (1) {
+	        	if ( buf[k]==10 || buf[k]==13 ) 
+	        		buf[k] = 0;	
+	        	if ( buf[k]==0 ) 
+	        		break;
+	        	k++;
+	        }
+	        printf(":street: %s\n", buf );  
+	}        
+	fflush(0);
+#endif
+
+#if AS_WITH_LDAP	
+	// TODO :1:
+        if (0) printf(":1: \n");
+        if (state && strlen(state)) printf(":st: %s\n", state);
+        if (country) printf(":co: %s\n", country);
+        fflush(0);
+#endif
+        
+        if (keywords && (0 < keywords->cValues) && (keywords->cValues < 19)) {
+                /*
+                        limit on cValue prevents from unreasonable (probably undefined) values, limit of 19 is arbitrary
+                        cValues up to 6 have been observed        
+                */
+#if 0
+                // each keyword in a separate line
+                uint32_t k=0;
+                for (k=0; k<keywords->cValues; k++) 
+                        printf("Keywords: %s%s",keywords->strings[k].lppszW, RECSEP);
+#else
+                // keywords in a single line separated by semicolons
+                uint32_t k=0; 
+                printf("Keywords: %s",keywords->strings[k].lppszW);
+                fflush(0);
+                while (++k < keywords->cValues) printf("; %s", keywords->strings[k].lppszW);
+                printf("%s", RECSEP); 
+#endif
+#if AS_WITH_LDAP
+                for (k = 0; k < keywords->cValues; k++) {
+		        printf(":category: %s\n", keywords->strings[k].lppszW);	
+		}        
+#endif
+	}	
+        
+//	printf("%s", RECSEP);
+        fflush(0);
+ 
 }
 
+
+
 _PUBLIC_ const char *get_task_status(uint32_t status)
 {
 	switch (status) {
Index: script/samba4_ver.sh
===================================================================
--- script/samba4_ver.sh	(revision 3211)
+++ script/samba4_ver.sh	(working copy)
@@ -1,4 +1,4 @@
 SAMBA4_GIT_REV=
-SAMBA4_GIT_VER=4.0.0alpha17
-SAMBA4_RELEASE=4.0.0alpha17
+SAMBA4_GIT_VER=4.0.0alpha16
+SAMBA4_RELEASE=4.0.0alpha16
 
MAILBOX (1586 messages)

|== MusterMan, Fred ==| : 4D750AB800000001/F057AC37C01000B
Topic: Fred MusterMan
Canonical name: Fred MusterMan
Full Name: MusterMan Fred
Initials: F.M.
Name Prefix: 
Given Name: Fred
Surname: MusterMan
Job Title: 
Department: 
Company: 
E-mail1: yes@no
Office phone number: 098765654321
Locality: 
State / Province: 
Country: 

|== MusterFrau211 ==| : 4D750AB800000001/D057AC37C01000B
Topic: Must
Canonical name:  MusterFrau211
Full Name: MusterFrau211
Initials: M.
Name Prefix: 
Given Name: 
Surname: MusterFrau211
Job Title: TestSchl'aferin
Department: 
Company: 
E-mail1: MusterFrau <[email protected]>
Home phone number: new home phone number
Mobile phone number: 01234567689
Business home page: http://www.ist.ac.at
Locality: 
State / Province: 
Country: 

Attachment: test_oc2db.pl
Description: Perl program

_______________________________________________
devel mailing list
[email protected]
http://mailman.openchange.org/listinfo/devel

Reply via email to