2 from select import select
6 LATCP_SOCKET = '/var/run/latlogin'
10 LATCP_CMD_TERMINALSESSION = 26
11 LATCP_CMD_ERRORMSG = 99
13 class LATClientException(Exception): pass
15 def read_for_a_bit(rfh):
18 r = select([rfh], [], [], 5.0)[0]
26 message = message + ch
29 print "Received message: ", repr(message)
32 def write_and_get_response(rfh, wfh, message, expect_echo=True):
33 print "Writing message:", repr(message)
34 wfh.write(message+'\r\n')
37 response = read_for_a_bit(rfh)
38 if response.find(message) == -1 and expect_echo:
39 raise LATClientException("Talking to DEC server, expected to find original message in echo but didn't")
43 def __init__(self, service = None, node = None, port = None,
44 localport = None, password = None, is_queued = False,
45 server_name = '', connect_password='', priv_password=''):
47 self.server_name = server_name
48 self.connect_password = connect_password
49 self.priv_password = priv_password
51 self.sock = socket(AF_UNIX, SOCK_STREAM, 0);
52 self.sock.connect(LATCP_SOCKET)
53 self.send_msg(LATCP_CMD_VERSION, LAT_VERSION+'\000')
54 (cmd, msg) = self.read_reply()
55 if service == None: service = ''
56 if node == None: node = ''
57 if port == None: port = ''
58 if localport == None: localport = ''
59 if password == None: password = ''
64 self.send_msg(LATCP_CMD_TERMINALSESSION, '%c%c%s%c%s%c%s%c%s%c%s' % \
66 len(service), service,
69 len(localport), localport,
70 len(password), password
72 (cmd, msg) = self.read_reply()
73 if ord(cmd) == LATCP_CMD_ERRORMSG:
74 raise LATClientException(msg)
76 self.rfh = self.sock.makefile('r')
77 self.wfh = self.sock.makefile('w')
79 r = select([self.rfh], [], [], 2.0)[0]
81 l = self.rfh.readline()
82 if l.find('Service in use') >= 0:
83 print "Service in use, apparently: restarting DEC server"
94 def send_msg(self, cmd, msg):
95 self.sock.send('%c%c%c%s'%(cmd, len(msg)/256, len(msg)%256, msg))
97 def reboot_server(self):
100 mopw, mopr = popen4('/usr/sbin/moprc '+self.server_name)
101 write_and_get_response(mopr, mopw, '')
102 r = write_and_get_response(mopr, mopw, self.connect_password, False)
103 if r.find('Enter username> ') == -1:
104 print "Expected username prompt, got ", repr(r)
105 raise LATClientException('failed to reboot server')
106 r = write_and_get_response(mopr, mopw, 'grim reaper')
107 if r.find('Local> ') == -1:
108 print "Expected DEC server prompt, got ", repr(r)
109 raise LATClientException('failed to reboot server')
110 r = write_and_get_response(mopr, mopw, 'set priv')
111 if r.find('Password> ') == -1:
112 print "Expected priv password prompt, got ", repr(r)
113 raise LATClientException('failed to reboot server')
114 r = write_and_get_response(mopr, mopw, self.priv_password, False)
115 if r.find('Local> ') == -1:
116 print "Expected DEC server prompt, got ", repr(r)
117 raise LATClientException('failed to reboot server')
118 r = write_and_get_response(mopr, mopw, 'init del 0')
119 if r.find('Target does not respond') == -1:
120 print "Expected DEC server to die, got ", repr(r)
121 raise LATClientException('failed to reboot server')
125 print "Waiting 10 seconds for DEC server to come back to life..."
127 print "Rightyo, back to vending!"
129 raise LATClientException('needed to reboot server')
131 def read_reply(self):
132 head = self.sock.recv(3)
134 raise LATClientException('Short LAT packet')
136 length = ord(head[1])*256 + ord(head[2])
137 msg = self.sock.recv(length)
138 if cmd == LATCP_CMD_ERRORMSG:
139 raise LATClientException('Received LAT error: %s'%msg)
143 return (self.rfh, self.wfh)