summaryrefslogtreecommitdiff
path: root/source4/lib/ldb/ldb_tdb/ldb_pack.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-04-03 12:29:21 +0000
committerAndrew Tridgell <tridge@samba.org>2004-04-03 12:29:21 +0000
commitee44733f94864fb0a1ae15d48e3335c0705a82ae (patch)
tree8f9691975aab7a6ce3736e64283e66a69db3c194 /source4/lib/ldb/ldb_tdb/ldb_pack.c
parentf1c3fa060efcecde404d0bfb55c359ef7fe36ed8 (diff)
downloadsamba-ee44733f94864fb0a1ae15d48e3335c0705a82ae.tar.gz
samba-ee44733f94864fb0a1ae15d48e3335c0705a82ae.tar.bz2
samba-ee44733f94864fb0a1ae15d48e3335c0705a82ae.zip
added the rest of the ldb_modify() code, which required a fairly large
change in the ldb API. The API is now much closer to LDAP. (This used to be commit e9e85c464411c561c5073d262a2e3533fec175ca)
Diffstat (limited to 'source4/lib/ldb/ldb_tdb/ldb_pack.c')
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_pack.c94
1 files changed, 69 insertions, 25 deletions
diff --git a/source4/lib/ldb/ldb_tdb/ldb_pack.c b/source4/lib/ldb/ldb_tdb/ldb_pack.c
index b0c825e8e2..1b0c8a1857 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_pack.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_pack.c
@@ -41,13 +41,16 @@
/*
pack a ldb message into a linear buffer in a TDB_DATA
+ note that this routine avoids saving elements with zero values,
+ as these are equivalent to having no element
+
caller frees the data buffer after use
*/
int ltdb_pack_data(struct ldb_context *ctx,
const struct ldb_message *message,
struct TDB_DATA *data)
{
- int i;
+ int i, j;
size_t size;
char *p;
@@ -55,8 +58,13 @@ int ltdb_pack_data(struct ldb_context *ctx,
size = 8;
for (i=0;i<message->num_elements;i++) {
- size += 1 + strlen(message->elements[i].name);
- size += 4 + message->elements[i].value.length + 1;
+ if (message->elements[i].num_values == 0) {
+ continue;
+ }
+ size += 1 + strlen(message->elements[i].name) + 4;
+ for (j=0;j<message->elements[i].num_values;j++) {
+ size += 4 + message->elements[i].values[j].length + 1;
+ }
}
/* allocate it */
@@ -73,28 +81,50 @@ int ltdb_pack_data(struct ldb_context *ctx,
p += 8;
for (i=0;i<message->num_elements;i++) {
- size_t len = strlen(message->elements[i].name);
+ size_t len;
+ if (message->elements[i].num_values == 0) {
+ continue;
+ }
+ len = strlen(message->elements[i].name);
memcpy(p, message->elements[i].name, len+1);
p += len + 1;
- SIVAL(p, 0, message->elements[i].value.length);
- memcpy(p+4, message->elements[i].value.data,
- message->elements[i].value.length);
- p[4+message->elements[i].value.length] = 0;
- p += 4 + message->elements[i].value.length + 1;
+ SIVAL(p, 0, message->elements[i].num_values);
+ p += 4;
+ for (j=0;j<message->elements[i].num_values;j++) {
+ SIVAL(p, 0, message->elements[i].values[j].length);
+ memcpy(p+4, message->elements[i].values[j].data,
+ message->elements[i].values[j].length);
+ p[4+message->elements[i].values[j].length] = 0;
+ p += 4 + message->elements[i].values[j].length + 1;
+ }
}
return 0;
}
+/*
+ free the memory allocated from a ltdb_unpack_data()
+*/
+void ltdb_unpack_data_free(struct ldb_message *message)
+{
+ int i;
+
+ for (i=0;i<message->num_elements;i++) {
+ if (message->elements[i].values) free(message->elements[i].values);
+ }
+ if (message->elements) free(message->elements);
+}
+
/*
unpack a ldb message from a linear buffer in TDB_DATA
note that this does not fill in the class and key elements
- caller frees. Memory for the elements[] array is malloced,
- but the memory for the elements is re-used from the TDB_DATA
- data. This means the caller only has to free the elements array
+ caller frees. Memory for the elements[] and values[] arrays are
+ malloced, but the memory for the elements is re-used from the
+ TDB_DATA data. This means the caller only has to free the elements
+ and values arrays. This can be done with ltdb_unpack_data_free()
*/
int ltdb_unpack_data(struct ldb_context *ctx,
const struct TDB_DATA *data,
@@ -102,7 +132,7 @@ int ltdb_unpack_data(struct ldb_context *ctx,
{
char *p;
unsigned int remaining;
- int i;
+ int i, j;
message->elements = NULL;
@@ -145,30 +175,44 @@ int ltdb_unpack_data(struct ldb_context *ctx,
for (i=0;i<message->num_elements;i++) {
size_t len;
- if (remaining < 6) {
+ if (remaining < 10) {
errno = EIO;
goto failed;
}
len = strnlen(p, remaining-6);
+ message->elements[i].flags = 0;
message->elements[i].name = p;
remaining -= len + 1;
p += len + 1;
- len = IVAL(p, 0);
- if (len > remaining-5) {
- errno = EIO;
- goto failed;
+ message->elements[i].num_values = IVAL(p, 0);
+ message->elements[i].values = NULL;
+ if (message->elements[i].num_values != 0) {
+ message->elements[i].values = malloc_array_p(struct ldb_val,
+ message->elements[i].num_values);
+ if (!message->elements[i].values) {
+ errno = ENOMEM;
+ goto failed;
+ }
+ }
+ p += 4;
+ for (j=0;j<message->elements[i].num_values;j++) {
+ len = IVAL(p, 0);
+ if (len > remaining-5) {
+ errno = EIO;
+ goto failed;
+ }
+
+ message->elements[i].values[j].length = len;
+ message->elements[i].values[j].data = p+4;
+ remaining -= len+4+1;
+ p += len+4+1;
}
- message->elements[i].value.length = len;
- message->elements[i].value.data = p+4;
- remaining -= len+4+1;
- p += len+4+1;
}
return 0;
failed:
- if (message->elements) {
- free(message->elements);
- }
+ ltdb_unpack_data_free(message);
+
return -1;
}