def Run(self, args): """Run.""" time_start = rdfvalue.RDFDatetime.Now() args.python_code.Verify( config.CONFIG["Client.executable_signing_public_key"]) # The execed code can assign to this variable if it wants to return data. logging.debug("exec for python code %s", args.python_code.data[0:100]) context = globals().copy() context["py_args"] = args.py_args.ToDict() context["magic_return_str"] = "" # Export the Progress function to allow python hacks to call it. context["Progress"] = self.Progress stdout = io.StringIO() with utils.Stubber(sys, "stdout", StdOutHook(stdout)): exec(args.python_code.data, context) # pylint: disable=exec-used stdout_output = stdout.getvalue() magic_str_output = context.get("magic_return_str") if stdout_output and magic_str_output: output = "Stdout: %s\nMagic Str:%s\n" % (stdout_output, magic_str_output) else: output = stdout_output or magic_str_output time_used = rdfvalue.RDFDatetime.Now() - time_start self.SendReply( rdf_client_action.ExecutePythonResponse(time_used=time_used.ToInt( rdfvalue.MICROSECONDS), return_val=output))
def Run(self, args): """Run.""" time_start = time.time() class StdOutHook(object): def __init__(self, buf): self.buf = buf def write(self, text): self.buf.write(text) args.python_code.Verify( config.CONFIG["Client.executable_signing_public_key"]) # The execed code can assign to this variable if it wants to return data. logging.debug("exec for python code %s", args.python_code.data[0:100]) context = globals().copy() context["py_args"] = args.py_args.ToDict() context["magic_return_str"] = "" # Export the Progress function to allow python hacks to call it. context["Progress"] = self.Progress # TODO(hanuszczak): In Python 3 writing to stdout is writing human readable # text so `StringIO` is better fit. Actions should be refactored so that # they write unicode (probably they already do) instead of arbitrary stream # of bytes. stdout = io.BytesIO() with utils.Stubber(sys, "stdout", StdOutHook(stdout)): exec(args.python_code.data, context) # pylint: disable=exec-used stdout_output = stdout.getvalue() magic_str_output = context.get("magic_return_str") if stdout_output and magic_str_output: output = "Stdout: %s\nMagic Str:%s\n" % (stdout_output, magic_str_output) else: output = stdout_output or magic_str_output time_used = time.time() - time_start # We have to return microseconds. self.SendReply( rdf_client_action.ExecutePythonResponse( time_used=int(1e6 * time_used), return_val=utils.SmartStr(output)))