From 9e603dfb95f61a7daf2acc80c9c3120ae9ecf98e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 28 Dec 2009 13:53:18 +0100 Subject: s4/net: Support parsing arguments in Python commands. --- source4/scripting/python/samba/netcmd/__init__.py | 64 ++++++++++++++++++++-- source4/utils/net/net.c | 65 ++++++++++++++++++----- 2 files changed, 112 insertions(+), 17 deletions(-) (limited to 'source4') diff --git a/source4/scripting/python/samba/netcmd/__init__.py b/source4/scripting/python/samba/netcmd/__init__.py index f644febba6..16f19f8b24 100644 --- a/source4/scripting/python/samba/netcmd/__init__.py +++ b/source4/scripting/python/samba/netcmd/__init__.py @@ -17,21 +17,79 @@ # along with this program. If not, see . # +import optparse +from samba import getopt as options, Ldb + + +class Option(optparse.Option): + pass + + class Command(object): """A net command.""" def _get_description(self): - return self.__doc__ + return self.__doc__.splitlines()[-1].rstrip("\n") + + def _get_name(self): + name = self.__class__.__name__ + if name.startswith("cmd_"): + return name[4:] + return name + + name = property(_get_name) def usage(self): - raise NotImplementedError + self.parser.print_usage() description = property(_get_description) + takes_args = [] + takes_options = [] + + def __init__(self): + synopsis = self.name + if self.takes_args: + synopsis += " " + " ".join(self.takes_args) + self.parser = optparse.OptionParser(synopsis) + self.parser.add_options(self.takes_options) + + def _run(self, *argv): + opts, args = self.parser.parse_args(list(argv)) + return self.run(*args, **opts.__dict__) + def run(self): """Run the command. This should be overriden by all subclasses.""" raise NotImplementedError(self.run) +class SuperCommand(Command): + """A command with subcommands.""" + + subcommands = {} + + def run(self, subcommand, *args, **kwargs): + if not subcommand in subcommands: + print >>sys.stderr, "No such subcommand '%s'" % subcommand + return subcommands[subcommand].run(*args, **kwargs) + + def usage(self, subcommand=None, *args, **kwargs): + if subcommand is None: + print "Available subcommands" + for subcommand in subcommands: + print "\t%s" % subcommand + return 0 + else: + if not subcommand in subcommands: + print >>sys.stderr, "No such subcommand '%s'" % subcommand + return subcommands[subcommand].usage(*args, **kwargs) + + +class FooCommand(Command): + + def run(self, bar): + print "LALALA" + bar + return 0 + commands = {} -commands["foo"] = Command() +commands["foo"] = FooCommand() diff --git a/source4/utils/net/net.c b/source4/utils/net/net.c index 298204b01f..31bade32a5 100644 --- a/source4/utils/net/net.c +++ b/source4/utils/net/net.c @@ -52,6 +52,51 @@ #include #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; + } + + return PyInt_AsLong(ret); +} + static PyObject *py_commands(void) { PyObject *netcmd_module, *py_cmds; @@ -106,12 +151,8 @@ int net_run_function(struct net_context *ctx, py_cmd = PyDict_GetItemString(py_cmds, argv[0]); if (py_cmd != NULL) { - PyObject *ret = PyObject_CallMethod(py_cmd, "run", ""); - if (ret == NULL) { - PyErr_Print(); - return 1; - } - return PyInt_AsLong(ret); + return py_call_with_string_args(py_cmd, "_run", + argc-1, argv+1); } d_printf("No command: %s\n", argv[0]); @@ -142,12 +183,8 @@ int net_run_usage(struct net_context *ctx, py_cmd = PyDict_GetItemString(py_cmds, argv[0]); if (py_cmd != NULL) { - PyObject *ret = PyObject_CallMethod(py_cmd, "usage", ""); - if (ret == NULL) { - PyErr_Print(); - return 1; - } - return PyInt_AsLong(ret); + return py_call_with_string_args(py_cmd, "usage", argc-1, + argv+1); } d_printf("No usage information for command: %s\n", argv[0]); @@ -218,9 +255,9 @@ static int net_help_python(void) } desc = PyString_AsString(py_desc); if (strlen(name) > 7) { - d_printf("\t%s\t%s", name, desc); + d_printf("\t%s\t%s\n", name, desc); } else { - d_printf("\t%s\t\t%s", name, desc); + d_printf("\t%s\t\t%s\n", name, desc); } } return 0; -- cgit