summaryrefslogtreecommitdiff
path: root/source4/utils/net/net.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/utils/net/net.c')
-rw-r--r--source4/utils/net/net.c178
1 files changed, 169 insertions, 9 deletions
diff --git a/source4/utils/net/net.c b/source4/utils/net/net.c
index 828e46889e..ba935b9986 100644
--- a/source4/utils/net/net.c
+++ b/source4/utils/net/net.c
@@ -6,6 +6,7 @@
Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
Copyright (C) 2004 Stefan Metzmacher (metze@samba.org)
+ Copyright (C) 2009 Jelmer Vernooij (jelmer@samba.org)
Largely rewritten by metze in August 2004
@@ -48,6 +49,83 @@
#include "param/param.h"
#include "lib/events/events.h"
#include "auth/credentials/credentials.h"
+#include <Python.h>
+#include "scripting/python/modules.h"
+
+static PyObject *py_tuple_from_argv(int argc, const char *argv[])
+{
+ PyObject *l;
+ Py_ssize_t i;
+
+ l = PyTuple_New(argc);
+ if (l == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < argc; i++) {
+ PyTuple_SetItem(l, i, PyString_FromString(argv[i]));
+ }
+
+ return l;
+}
+
+static int py_call_with_string_args(PyObject *self, const char *method, int argc, const char *argv[])
+{
+ PyObject *ret, *args, *py_method;
+
+ args = py_tuple_from_argv(argc, argv);
+ if (args == NULL) {
+ PyErr_Print();
+ return 1;
+ }
+
+ py_method = PyObject_GetAttrString(self, method);
+ if (py_method == NULL) {
+ PyErr_Print();
+ return 1;
+ }
+
+ ret = PyObject_CallObject(py_method, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ PyErr_Print();
+ return 1;
+ }
+
+ if (ret == Py_None) {
+ return 0;
+ } else if (PyInt_Check(ret)) {
+ return PyInt_AsLong(ret);
+ } else {
+ fprintf(stderr, "Function return value type unexpected.\n");
+ return -1;
+ }
+}
+
+static PyObject *py_commands(void)
+{
+ PyObject *netcmd_module, *py_cmds;
+ netcmd_module = PyImport_ImportModule("samba.netcmd");
+ if (netcmd_module == NULL) {
+ PyErr_Print();
+ return NULL;
+ }
+
+ py_cmds = PyObject_GetAttrString(netcmd_module, "commands");
+ if (py_cmds == NULL) {
+ PyErr_Print();
+ return NULL;
+ }
+
+ if (!PyDict_Check(py_cmds)) {
+ d_printf("Python net commands is not a dictionary\n");
+ return NULL;
+ }
+
+ return py_cmds;
+}
/*
run a function from a function table. If not found then
@@ -84,6 +162,7 @@ int net_run_usage(struct net_context *ctx,
const struct net_functable *functable)
{
int i;
+ PyObject *py_cmds, *py_cmd;
for (i=0; functable[i].name; i++) {
if (strcasecmp_m(argv[0], functable[i].name) == 0)
@@ -92,6 +171,17 @@ int net_run_usage(struct net_context *ctx,
}
}
+ py_cmds = py_commands();
+ if (py_cmds == NULL) {
+ return 1;
+ }
+
+ py_cmd = PyDict_GetItemString(py_cmds, argv[0]);
+ if (py_cmd != NULL) {
+ return py_call_with_string_args(py_cmd, "usage", argc-1,
+ argv+1);
+ }
+
d_printf("No usage information for command: %s\n", argv[0]);
return 1;
@@ -112,13 +202,12 @@ static const struct net_functable net_functable[] = {
{NULL, NULL, NULL, NULL}
};
-int net_help(struct net_context *ctx, const struct net_functable *ftable)
+static int net_help_builtin(const struct net_functable *ftable)
{
int i = 0;
const char *name = ftable[i].name;
const char *desc = ftable[i].desc;
- d_printf("Available commands:\n");
while (name && desc) {
if (strlen(name) > 7) {
d_printf("\t%s\t%s", name, desc);
@@ -128,7 +217,53 @@ int net_help(struct net_context *ctx, const struct net_functable *ftable)
name = ftable[++i].name;
desc = ftable[i].desc;
}
+ return 0;
+}
+
+static int net_help_python(void)
+{
+ PyObject *py_cmds;
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+
+ py_cmds = py_commands();
+ if (py_cmds == NULL) {
+ return 1;
+ }
+
+ while (PyDict_Next(py_cmds, &pos, &key, &value)) {
+ char *name, *desc;
+ PyObject *py_desc;
+ if (!PyString_Check(key)) {
+ d_printf("Command name not a string\n");
+ return 1;
+ }
+ name = PyString_AsString(key);
+ py_desc = PyObject_GetAttrString(value, "description");
+ if (py_desc == NULL) {
+ PyErr_Print();
+ return 1;
+ }
+ if (!PyString_Check(py_desc)) {
+ d_printf("Command description for %s not a string\n",
+ name);
+ return 1;
+ }
+ desc = PyString_AsString(py_desc);
+ if (strlen(name) > 7) {
+ d_printf("\t%s\t%s\n", name, desc);
+ } else {
+ d_printf("\t%s\t\t%s\n", name, desc);
+ }
+ }
+ return 0;
+}
+int net_help(struct net_context *ctx, const struct net_functable *ftable)
+{
+ d_printf("Available commands:\n");
+ net_help_builtin(ftable);
+ net_help_python();
return 0;
}
@@ -148,6 +283,7 @@ static int binary_net(int argc, const char **argv)
int opt,i;
int rc;
int argc_new;
+ PyObject *py_cmds, *py_cmd;
const char **argv_new;
struct tevent_context *ev;
struct net_context *ctx = NULL;
@@ -163,6 +299,33 @@ static int binary_net(int argc, const char **argv)
setlinebuf(stdout);
+ dcerpc_init(cmdline_lp_ctx);
+
+ ev = s4_event_context_init(NULL);
+ if (!ev) {
+ d_printf("Failed to create an event context\n");
+ exit(1);
+ }
+ py_load_samba_modules();
+ Py_Initialize();
+ PySys_SetArgv(argc, argv);
+ py_update_path("bin"); /* FIXME: Can't assume this is always the case */
+
+ py_cmds = py_commands();
+ if (py_cmds == NULL) {
+ return 1;
+ }
+
+ if (argc > 1) {
+ py_cmd = PyDict_GetItemString(py_cmds, argv[1]);
+ if (py_cmd != NULL) {
+ rc = py_call_with_string_args(py_cmd, "_run",
+ argc-1, argv+1);
+ talloc_free(ev);
+ return rc;
+ }
+ }
+
pc = poptGetContext("net", argc, (const char **) argv, long_options,
POPT_CONTEXT_KEEP_FIRST);
@@ -190,13 +353,7 @@ static int binary_net(int argc, const char **argv)
return net_usage(ctx, argc, argv);
}
- dcerpc_init(cmdline_lp_ctx);
- ev = s4_event_context_init(NULL);
- if (!ev) {
- d_printf("Failed to create an event context\n");
- exit(1);
- }
ctx = talloc(ev, struct net_context);
if (!ctx) {
d_printf("Failed to talloc a net_context\n");
@@ -208,7 +365,10 @@ static int binary_net(int argc, const char **argv)
ctx->credentials = cmdline_credentials;
ctx->event_ctx = ev;
- rc = net_run_function(ctx, argc_new-1, argv_new+1, net_functable, net_usage);
+
+
+ rc = net_run_function(ctx, argc_new-1, argv_new+1, net_functable,
+ net_usage);
if (rc != 0) {
DEBUG(0,("return code = %d\n", rc));