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)
19 self.cl.sk.send(self.printer.pformat(ob) + "\n")
21 def command(self, cmd):
24 ccode = compile(cmd, "PDM Input", "eval")
26 ccode = compile(cmd, "PDM Input", "exec")
27 exec ccode in self.mod.__dict__
28 self.cl.sk.send("+OK\n")
30 self.echo(eval(ccode, self.mod.__dict__))
31 self.cl.sk.send("+OK\n")
33 for line in traceback.format_exception(*sys.exc_info()):
35 self.cl.sk.send("+EXC\n")
37 def handle(self, buf):
45 class client(threading.Thread):
46 def __init__(self, sk):
47 super(client, self).__init__(name = "Management client")
52 def choose(self, proto):
54 self.handler = repl(self)
56 self.sk.send("-ERR Unknown protocol: %s\n" % proto)
59 def handle(self, buf):
70 self.sk.send("+PDM1\n")
72 ret = self.sk.recv(1024)
78 nbuf = self.handler.handle(buf)
87 class listener(threading.Thread):
89 super(listener, self).__init__(name = "Management listener")
95 rfd, wfd, efd = select.select([sk], [], [sk], 1)
98 nsk, addr = sk.accept()
99 self.accept(nsk, addr)
105 def accept(self, sk, addr):
109 class unixlistener(listener):
110 def __init__(self, name, mode = 0600, group = None):
111 super(unixlistener, self).__init__()
117 sk = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
120 if os.path.exists(self.name) and os.path.stat.S_ISSOCK(os.stat(self.name).st_mode):
124 os.chmod(self.name, self.mode)
125 if self.group is not None:
126 os.chown(self.name, os.getuid(), grp.getgrnam(self.group).gr_gid)
134 class tcplistener(listener):
135 def __init__(self, port, bindaddr = "127.0.0.1"):
136 super(tcplistener, self).__init__()
138 self.bindaddr = bindaddr
141 sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
143 sk.bind((self.bindaddr, self.port))