1 """Management for daemon processes
3 This module contains a utility to listen for management commands on a
4 socket, lending itself to managing daemon processes.
7 import os, sys, socket, threading, grp, select
8 import types, pprint, traceback
11 def __init__(self, cl):
13 self.mod = types.ModuleType("repl")
14 self.mod.echo = self.echo
15 self.printer = pprint.PrettyPrinter(indent = 4, depth = 6)
18 def sendlines(self, text):
19 for line in text.split("\n"):
20 self.cl.sk.send(" " + line + "\n")
23 self.sendlines(self.printer.pformat(ob))
25 def command(self, cmd):
28 ccode = compile(cmd, "PDM Input", "eval")
30 ccode = compile(cmd, "PDM Input", "exec")
31 exec ccode in self.mod.__dict__
32 self.cl.sk.send("+OK\n")
34 self.echo(eval(ccode, self.mod.__dict__))
35 self.cl.sk.send("+OK\n")
37 for line in traceback.format_exception(*sys.exc_info()):
38 self.cl.sk.send(" " + line)
39 self.cl.sk.send("+EXC\n")
41 def handle(self, buf):
49 class client(threading.Thread):
50 def __init__(self, sk):
51 super(client, self).__init__(name = "Management client")
56 def choose(self, proto):
58 self.handler = repl(self)
60 self.sk.send("-ERR Unknown protocol: %s\n" % proto)
63 def handle(self, buf):
74 self.sk.send("+PDM1\n")
76 ret = self.sk.recv(1024)
82 nbuf = self.handler.handle(buf)
91 class listener(threading.Thread):
93 super(listener, self).__init__(name = "Management listener")
99 rfd, wfd, efd = select.select([sk], [], [sk], 1)
102 nsk, addr = sk.accept()
103 self.accept(nsk, addr)
109 def accept(self, sk, addr):
113 class unixlistener(listener):
114 def __init__(self, name, mode = 0600, group = None):
115 super(unixlistener, self).__init__()
121 sk = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
124 if os.path.exists(self.name) and os.path.stat.S_ISSOCK(os.stat(self.name).st_mode):
128 os.chmod(self.name, self.mode)
129 if self.group is not None:
130 os.chown(self.name, os.getuid(), grp.getgrnam(self.group).gr_gid)
138 class tcplistener(listener):
139 def __init__(self, port, bindaddr = "127.0.0.1"):
140 super(tcplistener, self).__init__()
142 self.bindaddr = bindaddr
145 sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
147 sk.bind((self.bindaddr, self.port))