From 920c37c3142095bed50beef03e07871f782761ff Mon Sep 17 00:00:00 2001 From: Daniel Folkinshteyn Date: Wed, 21 Jul 2010 12:48:46 -0400 Subject: [PATCH] Unix: add call command, giving owner ability to call any system command. --- plugins/Unix/plugin.py | 27 +++++++++++++++++++++++++++ plugins/Unix/test.py | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/plugins/Unix/plugin.py b/plugins/Unix/plugin.py index 2dd5ba7b3..5428f3d54 100644 --- a/plugins/Unix/plugin.py +++ b/plugins/Unix/plugin.py @@ -38,6 +38,7 @@ import random import select import struct import subprocess +import shlex import supybot.utils as utils from supybot.commands import * @@ -302,5 +303,31 @@ class Unix(callbacks.Plugin): 't':'positiveInt','W':'positiveInt'}), first('ip', ('matches', _hostExpr, 'Invalid hostname'))])) + def call(self, irc, msg, args, text): + """ + Calls any command available on the system, and returns its output. + Requires owner capability. + Note that being restricted to owner, this command does not do any + sanity checking on input/output. So it is up to you to make sure + you don't run anything that will spamify your channel or that + will bring your machine to its knees. + """ + args = shlex.split(text) + try: + inst = subprocess.Popen(args, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=file(os.devnull)) + except OSError, e: + irc.error('It seems the requested command was ' + 'not available (%s).' % e, Raise=True) + result = inst.communicate() + if result[1]: # stderr + irc.error(' '.join(result[1].split())) + if result[0]: # stdout + response = result[0].split("\n"); + response = [l for l in response if l] + irc.replies(response) + call = thread(wrap(call, ["owner", "text"])) + Class = Unix # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: diff --git a/plugins/Unix/test.py b/plugins/Unix/test.py index 86d73db50..e6ac42b84 100644 --- a/plugins/Unix/test.py +++ b/plugins/Unix/test.py @@ -87,4 +87,8 @@ if os.name == 'posix': self.assertNotError('unix ping --W 1 --c 1 127.0.0.1') self.assertError('unix ping --W a --c 1 127.0.0.1') + def testCall(self): + self.assertNotError('unix call /bin/ping -c 1 localhost') + self.assertRegexp('unix call /bin/ping -c 1 localhost', 'ping statistics') + self.assertError('unix call /usr/bin/nosuchcommandaoeuaoeu') # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: