poezio/src/daemon.py

81 lines
2.5 KiB
Python
Raw Normal View History

#/usr/bin/env python3
2011-10-29 03:13:12 +00:00
# Copyright 2011 Florent Le Coz <louiz@louiz.org>
#
# This file is part of Poezio.
#
# Poezio is free software: you can redistribute it and/or modify
# it under the terms of the zlib license. See the COPYING file.
"""
This file is a standalone program that reads commands on
stdin and executes them (each line should be a command).
2011-10-29 03:13:12 +00:00
Usage: cat some_fifo | ./daemon.py
2011-10-29 03:13:12 +00:00
Poezio writes commands in the fifo, and this daemon executes them on the
local machine.
2011-10-29 03:13:12 +00:00
Note that you should not start this daemon if you do not trust the remote
machine that is running poezio, since this could make it run any (dangerous)
command on your local machine.
"""
import sys
import threading
import subprocess
import shlex
2011-12-15 19:29:20 +00:00
import logging
log = logging.getLogger(__name__)
2011-10-29 03:13:12 +00:00
class Executor(threading.Thread):
"""
Just a class to execute commands in a thread. This way, the execution
can totally fail, we dont care, and we can start commands without
having to wait for them to return.
WARNING: Be careful to properly escape what is untrusted by using
pipes.quote (or shlex.quote with python 3.3) for example.
2011-10-29 03:13:12 +00:00
"""
2012-12-27 17:18:20 +00:00
def __init__(self, command, remote=False):
2011-10-29 03:13:12 +00:00
threading.Thread.__init__(self)
self.command = command
2012-12-27 17:18:20 +00:00
self.remote = remote
# check for > or >> special case
self.filename = None
self.redirection_mode = 'w'
if len(command) >= 3:
if command[-2] in ('>', '>>'):
self.filename = command.pop(-1)
if command[-1] == '>>':
self.redirection_mode = 'a'
command.pop(-1)
2011-10-29 03:13:12 +00:00
def run(self):
log.info('executing %s' % (self.command,))
stdout = None
if self.filename:
try:
stdout = open(self.filename, self.redirection_mode)
except (OSError, IOError) as e:
log.error('Could not open redirection file: %s (%s)' % (self.filename, e,))
return
2012-12-27 17:18:20 +00:00
try:
subprocess.call(self.command, stdout=stdout)
except:
import traceback
if self.remote:
print(traceback.format_exc())
else:
log.error('Could not execute %s:\n%s', self.command, traceback.format_exc())
2011-10-29 03:13:12 +00:00
def main():
2011-10-29 03:13:12 +00:00
while True:
line = sys.stdin.readline()
if line == '':
break
command = shlex.split(line)
2012-12-27 17:18:20 +00:00
e = Executor(command, remote=True)
e.start()
2011-10-29 03:13:12 +00:00
if __name__ == '__main__':
main()