new 'improved' (i.e. probably not working) code for rebooting dec server
[zanchey/dispense2.git] / sql-edition / servers / LATClient.py
index 4b2a1d9..fa2b297 100644 (file)
@@ -1,4 +1,7 @@
 from socket import *
+from select import select
+from os import popen4
+from time import sleep
 
 LATCP_SOCKET = '/var/run/latlogin'
 
@@ -7,9 +10,39 @@ LATCP_CMD_VERSION = 8
 LATCP_CMD_TERMINALSESSION = 26
 LATCP_CMD_ERRORMSG = 99
 
+class LATClientException(Exception): pass
+
+def read_for_a_bit(rfh):
+       message = ''
+       while 1:
+               r = select([rfh], [], [], 5.0)[0]
+               if r:
+                       message = message + rfh.read(1)
+               else:
+                       break
+       print "Received message: ", message
+       return message
+
+def write_expecting_echo(rfh, wfh, message):
+       print "Writing message:",message
+       while len(message) > 0:
+               wfh.write(message[0])
+               wfh.flush()
+               echo = rfh.read(1)
+               if echo != message[0]:
+                       print "Gah, expected echo when writing", message[0]
+               message = message[1:]
+       print "  --> Sent and echoed."
+
 class LATClient:
-       def __init__(self, service = None, node = None, port = None, \
-                       localport = None, password = None, is_queued = False):
+       def __init__(self, service = None, node = None, port = None,
+                    localport = None, password = None, is_queued = False,
+                    server_name = '', connect_password='', priv_password=''):
+
+               self.server_name = server_name
+               self.connect_password = connect_password
+               self.priv_password = priv_password
+               
                self.sock = socket(AF_UNIX, SOCK_STREAM, 0);
                self.sock.connect(LATCP_SOCKET)
                self.send_msg(LATCP_CMD_VERSION, LAT_VERSION+'\000')
@@ -32,23 +65,65 @@ class LATClient:
                         len(password), password
                         ))
                (cmd, msg) = self.read_reply()
-               if cmd == LATCP_CMD_ERRORMSG:
-                       raise Exception
+               if ord(cmd) == LATCP_CMD_ERRORMSG:
+                       raise LATClientException(msg)
+
+               self.rfh = self.sock.makefile('r')
+               self.wfh = self.sock.makefile('w')
+
+               r = select([self.rfh], [], [], 2.0)[0]
+               if r:
+                       l = self.rfh.readline()
+                       if l.find('Service in use') >= 0:
+                               print "Service in use, apparently: restarting DEC server"
+                               self.reboot_server()
+
+       def __del__(self):
+               try:
+                       self.sock.close()
+                       self.sock.shutdown(2)
+               except:
+                       pass
+               del self.sock
 
        def send_msg(self, cmd, msg):
                self.sock.send('%c%c%c%s'%(cmd, len(msg)/256, len(msg)%256, msg))
 
+       def reboot_server(self):
+               self.sock.shutdown(2)
+               self.sock.close()
+               mopw, mopr = popen4('/usr/sbin/moprc '+self.server_name)
+               write_expecting_echo(mopr, mopw, '\n')
+               read_for_a_bit(mopr)
+               write_expecting_echo(mopr, mopw, self.connect_password+'\n')
+               read_for_a_bit(mopr)
+               write_expecting_echo(mopr, mopw, 'grim reaper\n')
+               read_for_a_bit(mopr)
+               write_expecting_echo(mopr, mopw, 'set priv\n')
+               read_for_a_bit(mopr)
+               write_expecting_echo(mopr, mopw, self.priv_password+'\n')
+               read_for_a_bit(mopr)
+               write_expecting_echo(mopr, mopw, 'init del 0\n')
+               read_for_a_bit(mopr)
+               mopr.close()
+               mopw.close()
+               print
+               print "Waiting 10 seconds for DEC server to come back to life..."
+               sleep(10)
+               print "Rightyo, back to vending!"
+               print
+               raise LATClientException('needed to reboot server')
+
        def read_reply(self):
                head = self.sock.recv(3)
                if len(head) != 3:
-                       sys.stderr.write('Error: Short LAT packet\n')
-                       return None
+                       raise LATClientException('Short LAT packet')
                cmd = head[0]
                length = ord(head[1])*256 + ord(head[2])
                msg = self.sock.recv(length)
                if cmd == LATCP_CMD_ERRORMSG:
-                       sys.stderr.write('Error: Received LAT error: %s\n'%msg)
+                       raise LATClientException('Received LAT error: %s'%msg)
                return (cmd, msg)
        
        def get_fh(self):
-               return (self.sock.makefile('r'), self.sock.makefile('w'))
+               return (self.rfh, self.wfh)

UCC git Repository :: git.ucc.asn.au