2 from select import select
7 LATCP_SOCKET = '/var/run/latlogin'
10 LAT_VERSION = '1.24' # for running on Mermaid. [DAA] 20071107
12 LATCP_CMD_TERMINALSESSION = 26
13 LATCP_CMD_ERRORMSG = 99
15 class LATClientException(Exception): pass
17 def read_for_a_bit(rfh):
20 r = select([rfh], [], [], 5.0)[0]
28 message = message + ch
31 logging.debug("Received message: ", repr(message))
34 def write_and_get_response(rfh, wfh, message, expect_echo=True):
35 logging.debug("Writing message:", repr(message))
36 wfh.write(message+'\r\n')
38 logging.debug(" --> Sent")
39 response = read_for_a_bit(rfh)
40 if response.find(message) == -1 and expect_echo:
41 raise LATClientException("Talking to DEC server, expected to find original message in echo but didn't")
45 def __init__(self, service = None, node = None, port = None,
46 localport = None, password = None, is_queued = False,
47 server_name = '', connect_password='', priv_password=''):
49 self.server_name = server_name
50 self.connect_password = connect_password
51 self.priv_password = priv_password
53 self.sock = socket(AF_UNIX, SOCK_STREAM, 0);
54 self.sock.connect(LATCP_SOCKET)
55 self.send_msg(LATCP_CMD_VERSION, LAT_VERSION+'\000')
56 (cmd, msg) = self.read_reply()
57 if service == None: service = ''
58 if node == None: node = ''
59 if port == None: port = ''
60 if localport == None: localport = ''
61 if password == None: password = ''
66 self.send_msg(LATCP_CMD_TERMINALSESSION, '%c%c%s%c%s%c%s%c%s%c%s' % \
68 len(service), service,
71 len(localport), localport,
72 len(password), password
74 (cmd, msg) = self.read_reply()
75 if ord(cmd) == LATCP_CMD_ERRORMSG:
76 raise LATClientException(msg)
78 self.rfh = self.sock.makefile('r')
79 self.wfh = self.sock.makefile('w')
81 r = select([self.rfh], [], [], 2.0)[0]
83 l = self.rfh.readline()
84 if l.find('Service in use') >= 0:
85 logging.warning("Service in use, apparently: restarting DEC server")
96 def send_msg(self, cmd, msg):
97 self.sock.send('%c%c%c%s'%(cmd, len(msg)/256, len(msg)%256, msg))
99 def reboot_server(self):
100 self.sock.shutdown(2)
103 logging.info('Logging into DEC server')
104 mopw, mopr = popen4('/usr/sbin/moprc '+self.server_name)
105 write_and_get_response(mopr, mopw, '')
107 logging.info('Sending password')
108 r = write_and_get_response(mopr, mopw, self.connect_password, False)
109 if r.find('Enter username> ') == -1:
110 logging.warning("Expected username prompt, got " + repr(r))
111 raise LATClientException('failed to reboot server')
113 logging.info('Sending username')
114 r = write_and_get_response(mopr, mopw, 'grim reaper')
115 if r.find('Local> ') == -1:
116 logging.warning("Expected DEC server prompt, got " + repr(r))
117 raise LATClientException('failed to reboot server')
119 logging.info('Requesting privileges')
120 r = write_and_get_response(mopr, mopw, 'set priv')
121 if r.find('Password> ') == -1:
122 logging.warning("Expected priv password prompt, got " + repr(r))
123 raise LATClientException('failed to reboot server')
125 logging.info('Sending password')
126 r = write_and_get_response(mopr, mopw, self.priv_password, False)
127 if r.find('Local> ') == -1:
128 logging.warning("Expected DEC server prompt, got " + repr(r))
129 raise LATClientException('failed to reboot server')
131 logging.info('Sending reboot request')
132 r = write_and_get_response(mopr, mopw, 'init del 0')
133 if r.find('Target does not respond') == -1:
134 logging.warning("Expected DEC server to die, got " + repr(r))
135 raise LATClientException('failed to reboot server')
137 logging.info('Closed connection to server')
140 logging.info("Waiting 10 seconds for DEC server to come back to life...")
142 logging.info("Rightyo, back to vending!")
143 raise LATClientException('needed to reboot server')
145 def read_reply(self):
146 head = self.sock.recv(3)
148 raise LATClientException('Short LAT packet')
150 length = ord(head[1])*256 + ord(head[2])
151 msg = self.sock.recv(length)
152 if cmd == LATCP_CMD_ERRORMSG:
153 raise LATClientException('Received LAT error: %s'%msg)
157 return (self.rfh, self.wfh)