From 322023c0117556099864a82a1513c0c54707b482 Mon Sep 17 00:00:00 2001 From: nyuszika7h Date: Thu, 27 Feb 2014 15:46:38 +0100 Subject: [PATCH] Unix: Add @shell command --- plugins/Unix/plugin.py | 55 +++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/plugins/Unix/plugin.py b/plugins/Unix/plugin.py index 058d5a8f0..e5b365fb7 100644 --- a/plugins/Unix/plugin.py +++ b/plugins/Unix/plugin.py @@ -315,7 +315,7 @@ class Unix(callbacks.Plugin): _hostExpr = re.compile(r'^[a-z0-9][a-z0-9\.-]*[a-z0-9]$', re.I) ping = thread(wrap(ping, [getopts({'c':'positiveInt','i':'float', - 't':'positiveInt','W':'positiveInt'}), + 't':'positiveInt','W':'positiveInt'}), first('ip', ('matches', _hostExpr, 'Invalid hostname'))])) def sysuptime(self, irc, msg, args): @@ -328,10 +328,10 @@ class Unix(callbacks.Plugin): args = [uptimeCmd] try: with open(os.devnull) as null: - inst = subprocess.Popen(args, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - stdin=null) + inst = subprocess.Popen(args, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=null) except OSError as e: irc.error('It seems the configured uptime command was ' 'not available.', Raise=True) @@ -377,20 +377,21 @@ class Unix(callbacks.Plugin): 'variable appropriately.') 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. + you don't run anything that will spamify your channel or that + will bring your machine to its knees. """ args = shlex.split(text) try: with open(os.devnull) as null: - inst = subprocess.Popen(args, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - stdin=null) + inst = subprocess.Popen(args, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=null) except OSError as e: irc.error('It seems the requested command was ' 'not available (%s).' % e, Raise=True) @@ -398,10 +399,40 @@ class Unix(callbacks.Plugin): if result[1]: # stderr irc.error(' '.join(result[1].decode('utf8').split())) if result[0]: # stdout - response = result[0].decode('utf8').split("\n"); + response = result[0].decode('utf8').splitlines() response = [l for l in response if l] irc.replies(response) call = thread(wrap(call, ["owner", "text"])) + def shell(self, irc, msg, args, text): + """ + Calls any command available on the system using a shell, 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. + """ + try: + with open(os.devnull) as null: + inst = subprocess.Popen(text, + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=null) + except OSError as e: + irc.error('It seems the shell (%s) was not available (%s)' % + (os.getenv('SHELL'), e), Raise=True) + result = inst.communicate() + if result[1]: # stderr + irc.error(' '.join(result[1].decode('utf8').split())) + if result[0]: # stdout + response = result[0].decode('utf8').splitlines() + response = [l for l in response if l] + irc.replies(response) + shell = thread(wrap(shell, ["owner", "text"])) + + Class = Unix # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: