--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python/daemon.py Wed Jan 16 22:39:43 2008 +0100
@@ -0,0 +1,93 @@
+# Copyright (C) 1999,2000 Bruce Guenter <bruceg@em.ca>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import config
+
+ok = 0
+bad = 1
+err = 2
+econn = 3
+
+class Bad(Exception): pass
+class Error(Exception): pass
+class Econn(Exception): pass
+
+def encode_int(i):
+ return chr((i/256)%256) + chr(i%256)
+
+def encode_str(str):
+ return encode_int(len(str)) + str
+
+class Command:
+ def __init__(self, name, args):
+ self.name = name
+ self.args = args
+
+ def encode(self):
+ argcount = len(self.args)
+ cmd = chr(argcount) + encode_str(self.name)
+ for i in range(argcount):
+ cmd = cmd + encode_str(self.args[i])
+ cmd = chr(2) + encode_int(len(cmd)) + cmd
+ return cmd
+
+class Daemon:
+ def __init__(self):
+ self.socket_file = config.read('socket-file', '/tmp/.vmailmgrd')
+ self.socket = None
+
+ def connect(self):
+ import socket
+ self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ self.socket.connect(self.socket_file)
+
+ def read_response_noraise(self):
+ try:
+ reply = self.socket.recv(3)
+ code = ord(reply[0])
+ msglen = ord(reply[1])*256 + ord(reply[2])
+ message = self.socket.recv(msglen)
+ except:
+ return (econn, 'Server aborted the connection')
+ return (code, message)
+
+ def read_response(self):
+ (code, message) = self.read_response_noraise()
+ if code == err:
+ raise Error, message
+ if code == bad:
+ raise Bad, message
+ if code == econn:
+ raise Econn, message
+ return message
+
+ def execute(self, command):
+ try:
+ self.connect()
+ except:
+ raise Econn, "Unable to connect to the server"
+ data = command.encode()
+ try:
+ self.socket.send(data)
+ except:
+ raise Econn, "Server aborted the connection"
+ # Don't close the socket here -- it will be closed
+ # as soon as it gets garbage collected, and remains
+ # usable for other commands like listdomain.
+ return self.read_response()
+
+def execute(command, args):
+ return Daemon().execute(Command(command, args))