From 425386ff6141bba2e7b1d8f3c27e96aaf1c5cb95 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 26 Aug 2009 15:59:00 +1000 Subject: s4:ldb Add ldb_ldif_write_string() and python wrappers This allows us to turn a python LdbMessage back into a string. Andrew Bartlett --- source4/lib/ldb/common/ldb_ldif.c | 40 +++++++++++++++++++++++++++++++++++++ source4/lib/ldb/include/ldb.h | 14 +++++++++++++ source4/lib/ldb/pyldb.c | 38 +++++++++++++++++++++++++++++++++++ source4/lib/ldb/tests/python/api.py | 4 +++- 4 files changed, 95 insertions(+), 1 deletion(-) diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c index d890ff8300..30370e6999 100644 --- a/source4/lib/ldb/common/ldb_ldif.c +++ b/source4/lib/ldb/common/ldb_ldif.c @@ -759,3 +759,43 @@ int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif state.f = f; return ldb_ldif_write(ldb, fprintf_file, &state, ldif); } + +/* + wrapper around ldif_write() for a string +*/ +struct ldif_write_string_state { + char *string; +}; + +static int ldif_printf_string(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); + +static int ldif_printf_string(void *private_data, const char *fmt, ...) +{ + struct ldif_write_string_state *state = + (struct ldif_write_string_state *)private_data; + va_list ap; + size_t oldlen = strlen(state->string); + va_start(ap, fmt); + + state->string = talloc_vasprintf_append(state->string, fmt, ap); + va_end(ap); + if (!state->string) { + return -1; + } + + return strlen(state->string) - oldlen; +} + +char *ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + const struct ldb_ldif *ldif) +{ + struct ldif_write_string_state state; + state.string = talloc_strdup(mem_ctx, ""); + if (!state.string) { + return NULL; + } + if (ldb_ldif_write(ldb, ldif_printf_string, &state, ldif) == -1) { + return NULL; + } + return state.string; +} diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 20f0f9cc5a..8972fc83e9 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -1449,6 +1449,20 @@ struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s); */ int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *msg); +/** + Write an LDIF message to a string + + \param ldb the ldb context (from ldb_init()) + \param mem_ctx the talloc context on which to attach the string) + \param msg the message to write out + + \return the string containing the LDIF, or NULL on error + + \sa ldb_ldif_read_string for the reader equivalent to this function. +*/ +char * ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + const struct ldb_ldif *msg); + /** Base64 encode a buffer diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c index 94415c8c31..3f7fa2f395 100644 --- a/source4/lib/ldb/pyldb.c +++ b/source4/lib/ldb/pyldb.c @@ -813,6 +813,41 @@ static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif) } +static PyObject *py_ldb_write_ldif(PyLdbMessageObject *self, PyObject *args) +{ + int changetype; + PyObject *py_msg; + struct ldb_ldif ldif; + PyObject *ret; + char *string; + TALLOC_CTX *mem_ctx; + + if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype)) + return NULL; + + if (!PyLdbMessage_Check(py_msg)) { + PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg"); + return NULL; + } + + ldif.msg = PyLdbMessage_AsMessage(py_msg); + ldif.changetype = changetype; + + mem_ctx = talloc_new(NULL); + + string = ldb_ldif_write_string(PyLdb_AsLdbContext(self), mem_ctx, &ldif); + if (!string) { + PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF"); + return NULL; + } + + ret = PyString_FromString(string); + + talloc_free(mem_ctx); + + return ret; +} + static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args) { PyObject *list; @@ -1116,6 +1151,9 @@ static PyMethodDef py_ldb_methods[] = { { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS, "S.parse_ldif(ldif) -> iter(messages)\n" "Parse a string formatted using LDIF." }, + { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS, + "S.write_ldif(message, changetype) -> ldif\n" + "Print the message as a string formatted using LDIF." }, { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS, "S.msg_diff(Message) -> Message\n" "Return an LDB Message of the difference between two Message objects." }, diff --git a/source4/lib/ldb/tests/python/api.py b/source4/lib/ldb/tests/python/api.py index 9bcb225190..88983ac738 100755 --- a/source4/lib/ldb/tests/python/api.py +++ b/source4/lib/ldb/tests/python/api.py @@ -402,7 +402,9 @@ class DnTests(unittest.TestCase): msg = msgs.next() self.assertEquals("foo=bar", str(msg[1].dn)) self.assertTrue(isinstance(msg[1], ldb.Message)) - + ldif = self.ldb.write_ldif(msg[1], ldb.CHANGETYPE_NONE) + self.assertEquals("dn: foo=bar\n\n", ldif) + def test_parse_ldif_more(self): msgs = self.ldb.parse_ldif("dn: foo=bar\n\n\ndn: bar=bar") msg = msgs.next() -- cgit