svn commit: samba r4427 - in branches/SAMBA_4_0/source/lib/ldb: common include tools

tridge at samba.org tridge at samba.org
Fri Dec 31 03:51:42 GMT 2004


Author: tridge
Date: 2004-12-31 03:51:42 +0000 (Fri, 31 Dec 2004)
New Revision: 4427

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=4427

Log:
- added ldb_msg_*() functions for sorting, comparing and copying messages

- added a ldb_msg_canonicalize() function that fixes a record to not have any duplicate
  elements

- changed ldbedit to use ldb_msg_canonicalize(). This fixes a bug when you rename multiple
  elements in a record in one edit



Modified:
   branches/SAMBA_4_0/source/lib/ldb/common/ldb_msg.c
   branches/SAMBA_4_0/source/lib/ldb/include/ldb.h
   branches/SAMBA_4_0/source/lib/ldb/tools/ldbedit.c


Changeset:
Modified: branches/SAMBA_4_0/source/lib/ldb/common/ldb_msg.c
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/common/ldb_msg.c	2004-12-31 03:32:36 UTC (rev 4426)
+++ branches/SAMBA_4_0/source/lib/ldb/common/ldb_msg.c	2004-12-31 03:51:42 UTC (rev 4427)
@@ -228,6 +228,16 @@
 }
 
 /*
+  compare two ldb_message_element structures
+  comparing by element name
+*/
+int ldb_msg_element_compare_name(struct ldb_message_element *el1, 
+				 struct ldb_message_element *el2)
+{
+	return ldb_attr_cmp(el1->name, el2->name);
+}
+
+/*
   convenience functions to return common types from a message
   these return the first value if the attribute is multi-valued
 */
@@ -305,3 +315,127 @@
 	}
 	return v->data;
 }
+
+
+/*
+  sort the elements of a message by name
+*/
+void ldb_msg_sort_elements(struct ldb_message *msg)
+{
+	qsort(msg->elements, msg->num_elements, sizeof(struct ldb_message_element), 
+	      (comparison_fn_t)ldb_msg_element_compare_name);
+}
+
+
+/*
+  free a message created using ldb_msg_copy
+*/
+void ldb_msg_free(struct ldb_context *ldb, struct ldb_message *msg)
+{
+	int i, j;
+
+	for (i=0;i<msg->num_elements;i++) {
+		struct ldb_message_element *el = &msg->elements[i];
+		for (j=0;j<el->num_values;j++) {
+			ldb_free(ldb, el->values[j].data);
+		}
+		if (el->values) ldb_free(ldb, el->values);
+		ldb_free(ldb, el->name);
+	}
+	if (msg->elements) ldb_free(ldb, msg->elements);
+	ldb_free(ldb, msg->dn);
+	ldb_free(ldb, msg);
+}
+
+/*
+  copy a message, allocating new memory for all parts
+*/
+struct ldb_message *ldb_msg_copy(struct ldb_context *ldb, 
+				 const struct ldb_message *msg)
+{
+	struct ldb_message *msg2;
+	int i, j;
+
+	msg2 = ldb_malloc_p(ldb, struct ldb_message);
+	if (msg2 == NULL) return NULL;
+
+	msg2->elements = NULL;
+	msg2->num_elements = 0;
+	msg2->private_data = NULL;
+
+	msg2->dn = ldb_strdup(ldb, msg->dn);
+	if (msg2->dn == NULL) goto failed;
+
+	msg2->elements = ldb_malloc_array_p(ldb, struct ldb_message_element, msg->num_elements);
+	if (msg2->elements == NULL) goto failed;
+
+	for (i=0;i<msg->num_elements;i++) {
+		struct ldb_message_element *el1 = &msg->elements[i];
+		struct ldb_message_element *el2 = &msg2->elements[i];
+
+		el2->flags = el1->flags;
+		el2->num_values = 0;
+		el2->values = NULL;
+		el2->name = ldb_strdup(ldb, el1->name);
+		if (el2->name == NULL) goto failed;
+		el2->values = ldb_malloc_array_p(ldb, struct ldb_val, el1->num_values);
+		for (j=0;j<el1->num_values;j++) {
+			el2->values[j] = ldb_val_dup(ldb, &el1->values[j]);
+			if (el2->values[j].data == NULL &&
+			    el1->values[j].length != 0) {
+				goto failed;
+			}
+			el2->num_values++;
+		}
+
+		msg2->num_elements++;
+	}
+
+	return msg2;
+
+failed:
+	ldb_msg_free(ldb, msg2);
+	return NULL;
+}
+
+
+/*
+  canonicalise a message, merging elements of the same name
+*/
+struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, 
+					 const struct ldb_message *msg)
+{
+	int i;
+	struct ldb_message *msg2;
+
+	msg2 = ldb_msg_copy(ldb, msg);
+	if (msg2 == NULL) return NULL;
+
+	ldb_msg_sort_elements(msg2);
+
+	for (i=1;i<msg2->num_elements;i++) {
+		struct ldb_message_element *el1 = &msg2->elements[i-1];
+		struct ldb_message_element *el2 = &msg2->elements[i];
+		if (ldb_msg_element_compare_name(el1, el2) == 0) {
+			el1->values = ldb_realloc_p(ldb, el1->values, struct ldb_val, 
+						    el1->num_values + el2->num_values);
+			if (el1->values == NULL) {
+				return NULL;
+			}
+			memcpy(el1->values + el1->num_values,
+			       el2->values,
+			       sizeof(struct ldb_val) * el2->num_values);
+			el1->num_values += el2->num_values;
+			ldb_free(ldb, el2->name);
+			ldb_free(ldb, el2->values);
+			if (i+1<msg2->num_elements) {
+				memmove(el2, el2+1, sizeof(struct ldb_message_element) * 
+					(msg2->num_elements - (i+1)));
+			}
+			msg2->num_elements--;
+			i--;
+		}
+	}
+
+	return msg2;
+}

Modified: branches/SAMBA_4_0/source/lib/ldb/include/ldb.h
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/include/ldb.h	2004-12-31 03:32:36 UTC (rev 4426)
+++ branches/SAMBA_4_0/source/lib/ldb/include/ldb.h	2004-12-31 03:51:42 UTC (rev 4427)
@@ -293,6 +293,18 @@
 const char *ldb_msg_find_string(const struct ldb_message *msg, 
 				const char *attr_name,
 				const char *default_value);
+
+void ldb_msg_sort_elements(struct ldb_message *msg);
+
+void ldb_msg_free(struct ldb_context *ldb, struct ldb_message *msg);
+
+struct ldb_message *ldb_msg_copy(struct ldb_context *ldb, 
+				 const struct ldb_message *msg);
+
+struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, 
+					 const struct ldb_message *msg);
+
+
 struct ldb_val ldb_val_dup(struct ldb_context *ldb,
 			   const struct ldb_val *v);
 

Modified: branches/SAMBA_4_0/source/lib/ldb/tools/ldbedit.c
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/tools/ldbedit.c	2004-12-31 03:32:36 UTC (rev 4426)
+++ branches/SAMBA_4_0/source/lib/ldb/tools/ldbedit.c	2004-12-31 03:51:42 UTC (rev 4427)
@@ -69,6 +69,12 @@
 	mod.num_elements = 0;
 	mod.elements = NULL;
 
+	msg2 = ldb_msg_canonicalize(ldb, msg2);
+	if (msg2 == NULL) {
+		fprintf(stderr, "Failed to canonicalise msg2\n");
+		return -1;
+	}
+	
 	/* look in msg2 to find elements that need to be added
 	   or modified */
 	for (i=0;i<msg2->num_elements;i++) {
@@ -295,6 +301,7 @@
 	printf("  -b basedn        choose baseDN\n");
 	printf("  -a               edit all records (expression 'objectclass=*')\n");
 	printf("  -e editor        choose editor (or $VISUAL or $EDITOR)\n");
+	printf("  -v               verbose mode)\n");
 	exit(1);
 }
 



More information about the samba-cvs mailing list