python/daemon.py
changeset 0 6f7a81934006
child 2 b3afb9f1e801
equal deleted inserted replaced
-1:000000000000 0:6f7a81934006
       
     1 # Copyright (C) 1999,2000 Bruce Guenter <bruceg@em.ca>
       
     2 #
       
     3 # This program is free software; you can redistribute it and/or modify
       
     4 # it under the terms of the GNU General Public License as published by
       
     5 # the Free Software Foundation; either version 2 of the License, or
       
     6 # (at your option) any later version.
       
     7 #
       
     8 # This program is distributed in the hope that it will be useful,
       
     9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    11 # GNU General Public License for more details.
       
    12 #
       
    13 # You should have received a copy of the GNU General Public License
       
    14 # along with this program; if not, write to the Free Software
       
    15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    16 
       
    17 import config
       
    18 
       
    19 ok = 0
       
    20 bad = 1
       
    21 err = 2
       
    22 econn = 3
       
    23 
       
    24 class Bad(Exception):   pass
       
    25 class Error(Exception): pass
       
    26 class Econn(Exception): pass
       
    27 
       
    28 def encode_int(i):
       
    29     return chr((i/256)%256) + chr(i%256)
       
    30 
       
    31 def encode_str(str):
       
    32     return encode_int(len(str)) + str
       
    33 
       
    34 class Command:
       
    35     def __init__(self, name, args):
       
    36         self.name = name
       
    37         self.args = args
       
    38     
       
    39     def encode(self):
       
    40         argcount = len(self.args)
       
    41         cmd = chr(argcount) + encode_str(self.name)
       
    42         for i in range(argcount):
       
    43             cmd = cmd + encode_str(self.args[i])
       
    44         cmd = chr(2) + encode_int(len(cmd)) + cmd
       
    45         return cmd
       
    46 
       
    47 class Daemon:
       
    48     def __init__(self):
       
    49         self.socket_file = config.read('socket-file', '/tmp/.vmailmgrd')
       
    50         self.socket = None
       
    51 
       
    52     def connect(self):
       
    53         import socket
       
    54         self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
       
    55         self.socket.connect(self.socket_file)
       
    56 
       
    57     def read_response_noraise(self):
       
    58         try:
       
    59             reply = self.socket.recv(3)
       
    60             code = ord(reply[0])
       
    61             msglen = ord(reply[1])*256 + ord(reply[2])
       
    62             message = self.socket.recv(msglen)
       
    63         except:
       
    64             return (econn, 'Server aborted the connection')
       
    65         return (code, message)
       
    66         
       
    67     def read_response(self):
       
    68         (code, message) = self.read_response_noraise()
       
    69         if code == err:
       
    70             raise Error, message
       
    71         if code == bad:
       
    72             raise Bad, message
       
    73         if code == econn:
       
    74             raise Econn, message
       
    75         return message
       
    76         
       
    77     def execute(self, command):
       
    78         try:
       
    79             self.connect()
       
    80         except:
       
    81             raise Econn, "Unable to connect to the server"
       
    82         data = command.encode()
       
    83         try:
       
    84             self.socket.send(data)
       
    85         except:
       
    86             raise Econn, "Server aborted the connection"
       
    87         # Don't close the socket here -- it will be closed
       
    88         # as soon as it gets garbage collected, and remains
       
    89         # usable for other commands like listdomain.
       
    90         return self.read_response()
       
    91 
       
    92 def execute(command, args):
       
    93     return Daemon().execute(Command(command, args))