pidl/python: Factor out connect code rather than duplicating it in each
authorJelmer Vernooij <jelmer@samba.org>
Mon, 22 Dec 2008 03:56:41 +0000 (04:56 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Mon, 22 Dec 2008 03:56:41 +0000 (04:56 +0100)
Python module.

pidl/lib/Parse/Pidl/Samba4/Python.pm
source4/librpc/rpc/pyrpc.c
source4/librpc/rpc/pyrpc.h

index 378c40cc542b0de9d58d0c40ea53e9d46599cfa5..68e9c953957e6b1a131e04817e64bfff5d31ab7e 100644 (file)
@@ -673,89 +673,10 @@ sub Interface($$$)
                $self->pidl("static PyObject *interface_$interface->{NAME}_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)");
                $self->pidl("{");
                $self->indent;
-               $self->pidl("dcerpc_InterfaceObject *ret;");
-               $self->pidl("const char *binding_string;");
-               $self->pidl("struct cli_credentials *credentials;");
-               $self->pidl("struct loadparm_context *lp_ctx = NULL;");
-               $self->pidl("PyObject *py_lp_ctx = Py_None, *py_credentials = Py_None, *py_basis = Py_None;");
-               $self->pidl("TALLOC_CTX *mem_ctx = NULL;");
-               $self->pidl("struct event_context *event_ctx;");
-               $self->pidl("NTSTATUS status;");
-               $self->pidl("");
-               $self->pidl("const char *kwnames[] = {");
-               $self->indent;
-               $self->pidl("\"binding\", \"lp_ctx\", \"credentials\", \"basis_connection\", NULL");
-               $self->deindent;
-               $self->pidl("};");
-               $self->pidl("extern struct loadparm_context *lp_from_py_object(PyObject *py_obj);");
-               $self->pidl("extern struct cli_credentials *cli_credentials_from_py_object(PyObject *py_obj);");
-               $self->pidl("");
-               $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"s|OOO:$interface->{NAME}\", discard_const_p(char *, kwnames), &binding_string, &py_lp_ctx, &py_credentials, &py_basis)) {");
-               $self->indent;
-               $self->pidl("return NULL;");
-               $self->deindent;
-               $self->pidl("}");
-               $self->pidl("");
-               $self->pidl("lp_ctx = lp_from_py_object(py_lp_ctx);");
-               $self->pidl("if (lp_ctx == NULL) {");
-               $self->indent;
-               $self->pidl("PyErr_SetString(PyExc_TypeError, \"Expected loadparm context\");");
-               $self->pidl("return NULL;");
-               $self->deindent;
-               $self->pidl("}");
-               $self->pidl("");
-
-               $self->pidl("status = dcerpc_init(lp_ctx);");
-               $self->pidl("if (!NT_STATUS_IS_OK(status)) {");
-               $self->indent;
-               $self->pidl("PyErr_SetNTSTATUS(status);");
-               $self->pidl("return NULL;");
-               $self->deindent;
-               $self->pidl("}");
-
-               $self->pidl("credentials = cli_credentials_from_py_object(py_credentials);");
-               $self->pidl("if (credentials == NULL) {");
-               $self->indent;
-               $self->pidl("PyErr_SetString(PyExc_TypeError, \"Expected credentials\");");
-               $self->pidl("return NULL;");
+               $self->pidl("return py_dcerpc_interface_init_helper(type, args, kwargs, &ndr_table_$interface->{NAME});");
                $self->deindent;
                $self->pidl("}");
-
-               $self->pidl("ret = PyObject_New(dcerpc_InterfaceObject, type);");
-               $self->pidl("");
-               $self->pidl("event_ctx = event_context_init(mem_ctx);");
-               $self->pidl("");
-
-               $self->pidl("if (py_basis != Py_None) {");
-               $self->indent;
-               $self->pidl("struct dcerpc_pipe *base_pipe;");
-               $self->pidl("");
-               $self->pidl("if (!PyObject_TypeCheck(py_basis, &dcerpc_InterfaceType)) {");
-               $self->indent;
-               $self->pidl("PyErr_SetString(PyExc_ValueError, \"basis_connection must be a DCE/RPC connection\");");
-               $self->pidl("talloc_free(mem_ctx);");
-               $self->pidl("return NULL;");
-               $self->deindent;
-               $self->pidl("}");
-               $self->pidl("");
-               $self->pidl("base_pipe = ((dcerpc_InterfaceObject *)py_basis)->pipe;");
-               $self->pidl("");
-               $self->pidl("status = dcerpc_secondary_context(base_pipe, &ret->pipe, &ndr_table_$interface->{NAME});");
-               $self->deindent;
-               $self->pidl("} else {");
-               $self->indent;
-               $self->pidl("status = dcerpc_pipe_connect(NULL, &ret->pipe, binding_string, ");
-               $self->pidl("             &ndr_table_$interface->{NAME}, credentials, event_ctx, lp_ctx);");
-               $self->deindent;
-               $self->pidl("}");
-               $self->handle_ntstatus("status", "NULL", "mem_ctx");
-
-               $self->pidl("ret->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC;");
-
-               $self->pidl("return (PyObject *)ret;");
-               $self->deindent;
-               $self->pidl("}");
-               
+       
                $self->pidl("");
 
                my $signature = 
@@ -1202,7 +1123,6 @@ sub Parse($$$$$)
 #include \"librpc/rpc/dcerpc.h\"
 #include \"lib/talloc/pytalloc.h\"
 #include \"librpc/rpc/pyrpc.h\"
-#include \"lib/events/events.h\"
 #include \"$hdr\"
 #include \"$ndr_hdr\"
 
index 83bd64258178dd739a95948e2cf1a0f4ddb1509f..53a083e7403e4f88ac71ecd44ef9596cda733e9e 100644 (file)
@@ -251,7 +251,7 @@ static PyObject *py_iface_request(PyObject *self, PyObject *args, PyObject *kwar
        return ret;
 }
 
-static PyObject *py_iface_later_context(PyObject *self, PyObject *args, PyObject *kwargs)
+static PyObject *py_iface_alter_context(PyObject *self, PyObject *args, PyObject *kwargs)
 {
        dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)self;
        NTSTATUS status;
@@ -287,9 +287,75 @@ static PyObject *py_iface_later_context(PyObject *self, PyObject *args, PyObject
        return Py_None;
 }
 
+PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, PyObject *kwargs, const struct ndr_interface_table *table)
+{
+       dcerpc_InterfaceObject *ret;
+       const char *binding_string;
+       struct cli_credentials *credentials;
+       struct loadparm_context *lp_ctx = NULL;
+       PyObject *py_lp_ctx = Py_None, *py_credentials = Py_None, *py_basis = Py_None;
+       TALLOC_CTX *mem_ctx = NULL;
+       struct event_context *event_ctx;
+       NTSTATUS status;
+
+       const char *kwnames[] = {
+               "binding", "lp_ctx", "credentials", "basis_connection", NULL
+       };
+       extern struct cli_credentials *cli_credentials_from_py_object(PyObject *py_obj);
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|OOO:samr", discard_const_p(char *, kwnames), &binding_string, &py_lp_ctx, &py_credentials, &py_basis)) {
+               return NULL;
+       }
+
+       lp_ctx = lp_from_py_object(py_lp_ctx);
+       if (lp_ctx == NULL) {
+               PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
+               return NULL;
+       }
+
+       status = dcerpc_init(lp_ctx);
+       if (!NT_STATUS_IS_OK(status)) {
+               PyErr_SetNTSTATUS(status);
+               return NULL;
+       }
+       credentials = cli_credentials_from_py_object(py_credentials);
+       if (credentials == NULL) {
+               PyErr_SetString(PyExc_TypeError, "Expected credentials");
+               return NULL;
+       }
+       ret = PyObject_New(dcerpc_InterfaceObject, type);
+
+       event_ctx = event_context_init(mem_ctx);
+
+       if (py_basis != Py_None) {
+               struct dcerpc_pipe *base_pipe;
+
+               if (!PyObject_TypeCheck(py_basis, &dcerpc_InterfaceType)) {
+                       PyErr_SetString(PyExc_ValueError, "basis_connection must be a DCE/RPC connection");
+                       talloc_free(mem_ctx);
+                       return NULL;
+               }
+
+               base_pipe = ((dcerpc_InterfaceObject *)py_basis)->pipe;
+
+               status = dcerpc_secondary_context(base_pipe, &ret->pipe, table);
+       } else {
+               status = dcerpc_pipe_connect(NULL, &ret->pipe, binding_string, 
+                            table, credentials, event_ctx, lp_ctx);
+       }
+       if (NT_STATUS_IS_ERR(status)) {
+               PyErr_SetNTSTATUS(status);
+               talloc_free(mem_ctx);
+               return NULL;
+       }
+
+       ret->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC;
+       return (PyObject *)ret;
+}
+
 static PyMethodDef dcerpc_interface_methods[] = {
        { "request", (PyCFunction)py_iface_request, METH_VARARGS|METH_KEYWORDS, "S.request(opnum, data, object=None) -> data\nMake a raw request" },
-       { "alter_context", (PyCFunction)py_iface_later_context, METH_VARARGS|METH_KEYWORDS, "S.alter_context(syntax)\nChange to a different interface" },
+       { "alter_context", (PyCFunction)py_iface_alter_context, METH_VARARGS|METH_KEYWORDS, "S.alter_context(syntax)\nChange to a different interface" },
        { NULL, NULL, 0, NULL },
 };
 
index 3b2162ce1b7222dbf3164a6a8895b1ebf2d42a11..6d5193f57e4d56443a5686927e407c9d2bb1376b 100644 (file)
@@ -69,5 +69,6 @@ struct PyNdrRpcMethodDef {
 };
 
 bool PyInterface_AddNdrRpcMethods(PyTypeObject *object, const struct PyNdrRpcMethodDef *mds);
+PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, PyObject *kwargs, const struct ndr_interface_table *table);
 
 #endif /* _PYRPC_H_ */