+++ /dev/null
-"""Management for daemon processes
-
-This module contains a utility to listen for management commands on a
-socket, lending itself to managing daemon processes.
-"""
-
-import os, sys, socket, threading, grp, select
-import types, pprint, traceback
-
-class repl(object):
- def __init__(self, cl):
- self.cl = cl
- self.mod = types.ModuleType("repl")
- self.mod.echo = self.echo
- self.printer = pprint.PrettyPrinter(indent = 4, depth = 6)
- cl.sk.send("+REPL\n")
-
- def sendlines(self, text):
- for line in text.split("\n"):
- self.cl.sk.send(" " + line + "\n")
-
- def echo(self, ob):
- self.sendlines(self.printer.pformat(ob))
-
- def command(self, cmd):
- try:
- try:
- ccode = compile(cmd, "PDM Input", "eval")
- except SyntaxError:
- ccode = compile(cmd, "PDM Input", "exec")
- exec ccode in self.mod.__dict__
- self.cl.sk.send("+OK\n")
- else:
- self.echo(eval(ccode, self.mod.__dict__))
- self.cl.sk.send("+OK\n")
- except:
- for line in traceback.format_exception(*sys.exc_info()):
- self.cl.sk.send(" " + line)
- self.cl.sk.send("+EXC\n")
-
- def handle(self, buf):
- p = buf.find("\n\n")
- if p < 0:
- return buf
- cmd = buf[:p + 1]
- self.command(cmd)
- return buf[p + 2:]
-
-class client(threading.Thread):
- def __init__(self, sk):
- super(client, self).__init__(name = "Management client")
- self.setDaemon(True)
- self.sk = sk
- self.handler = self
-
- def choose(self, proto):
- if proto == "repl":
- self.handler = repl(self)
- else:
- self.sk.send("-ERR Unknown protocol: %s\n" % proto)
- raise Exception()
-
- def handle(self, buf):
- p = buf.find("\n")
- if p >= 0:
- proto = buf[:p]
- buf = buf[p + 1:]
- self.choose(proto)
- return buf
-
- def run(self):
- try:
- buf = ""
- self.sk.send("+PDM1\n")
- while True:
- ret = self.sk.recv(1024)
- if ret == "":
- return
- buf += ret
- while True:
- try:
- nbuf = self.handler.handle(buf)
- except:
- return
- if nbuf == buf:
- break
- buf = nbuf
- finally:
- self.sk.close()
-
-class listener(threading.Thread):
- def __init__(self):
- super(listener, self).__init__(name = "Management listener")
- self.setDaemon(True)
-
- def listen(self, sk):
- self.running = True
- while self.running:
- rfd, wfd, efd = select.select([sk], [], [sk], 1)
- for fd in rfd:
- if fd == sk:
- nsk, addr = sk.accept()
- self.accept(nsk, addr)
-
- def stop(self):
- self.running = False
- self.join()
-
- def accept(self, sk, addr):
- cl = client(sk)
- cl.start()
-
-class unixlistener(listener):
- def __init__(self, name, mode = 0600, group = None):
- super(unixlistener, self).__init__()
- self.name = name
- self.mode = mode
- self.group = group
-
- def run(self):
- sk = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- ul = False
- try:
- if os.path.exists(self.name) and os.path.stat.S_ISSOCK(os.stat(self.name).st_mode):
- os.unlink(self.name)
- sk.bind(self.name)
- ul = True
- os.chmod(self.name, self.mode)
- if self.group is not None:
- os.chown(self.name, os.getuid(), grp.getgrnam(self.group).gr_gid)
- sk.listen(16)
- self.listen(sk)
- finally:
- sk.close()
- if ul:
- os.unlink(self.name)
-
-class tcplistener(listener):
- def __init__(self, port, bindaddr = "127.0.0.1"):
- super(tcplistener, self).__init__()
- self.port = port
- self.bindaddr = bindaddr
-
- def run(self):
- sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- try:
- sk.bind((self.bindaddr, self.port))
- sk.listen(16)
- self.listen(sk)
- finally:
- sk.close()
+++ /dev/null
-"""Management for daemon processes
-
-This module provides some client support for the daemon management
-provided in the ashd.pdm module.
-"""
-
-import socket
-
-class protoerr(Exception):
- pass
-
-def resolve(spec):
- if isinstance(spec, socket.socket):
- return spec
- sk = None
- try:
- if "/" in spec:
- sk = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- sk.connect(spec)
- elif spec.isdigit():
- sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sk.connect(("localhost", int(spec)))
- elif ":" in spec:
- sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- p = spec.rindex(":")
- sk.connect((spec[:p], int(spec[p + 1:])))
- else:
- raise Exception("Unknown target specification %r" % spec)
- rv = sk
- sk = None
- finally:
- if sk is not None: sk.close()
- return rv
-
-class client(object):
- def __init__(self, sk, proto = None):
- self.sk = resolve(sk)
- self.buf = ""
- line = self.readline()
- if line != "+PDM1":
- raise protoerr("Illegal protocol signature")
- if proto is not None:
- self.select(proto)
-
- def close(self):
- self.sk.close()
-
- def readline(self):
- while True:
- p = self.buf.find("\n")
- if p >= 0:
- ret = self.buf[:p]
- self.buf = self.buf[p + 1:]
- return ret
- ret = self.sk.recv(1024)
- if ret == "":
- return None
- self.buf += ret
-
- def select(self, proto):
- if "\n" in proto:
- raise Exception("Illegal protocol specified: %r" % proto)
- self.sk.send(proto + "\n")
- rep = self.readline()
- if len(rep) < 1 or rep[0] != "+":
- raise protoerr("Error reply when selecting protocol %s: %s" % (proto, rep[1:]))
-
- def __enter__(self):
- return self
-
- def __exit__(self, *excinfo):
- self.close()
- return False
-
-class replclient(client):
- def __init__(self, sk):
- super(replclient, self).__init__(sk, "repl")
-
- def run(self, code):
- while True:
- ncode = code.replace("\n\n", "\n")
- if ncode == code: break
- code = ncode
- while len(code) > 0 and code[-1] == "\n":
- code = code[:-1]
- self.sk.send(code + "\n\n")
- buf = ""
- while True:
- ln = self.readline()
- if ln[0] == " ":
- buf += ln[1:] + "\n"
- elif ln[0] == "+":
- return buf
- elif ln[0] == "-":
- raise protoerr("Error reply: %s" % ln[1:])
- else:
- raise protoerr("Illegal reply: %s" % ln)