2 from select import select
7 LATCP_SOCKET = '/var/run/latlogin'
11 LATCP_CMD_TERMINALSESSION = 26
12 LATCP_CMD_ERRORMSG = 99
14 class LATClientException(Exception): pass
16 def read_for_a_bit(rfh):
19 r = select([rfh], [], [], 5.0)[0]
27 message = message + ch
30 logging.debug("Received message: ", repr(message))
33 def write_and_get_response(rfh, wfh, message, expect_echo=True):
34 logging.debug("Writing message:", repr(message))
35 wfh.write(message+'\r\n')
37 logging.debug(" --> Sent")
38 response = read_for_a_bit(rfh)
39 if response.find(message) == -1 and expect_echo:
40 raise LATClientException("Talking to DEC server, expected to find original message in echo but didn't")
44 def __init__(self, service = None, node = None, port = None,
45 localport = None, password = None, is_queued = False,
46 server_name = '', connect_password='', priv_password=''):
48 self.server_name = server_name
49 self.connect_password = connect_password
50 self.priv_password = priv_password
52 self.sock = socket(AF_UNIX, SOCK_STREAM, 0);
53 self.sock.connect(LATCP_SOCKET)
54 self.send_msg(LATCP_CMD_VERSION, LAT_VERSION+'\000')
55 (cmd, msg) = self.read_reply()
56 if service == None: service = ''
57 if node == None: node = ''
58 if port == None: port = ''
59 if localport == None: localport = ''
60 if password == None: password = ''
65 self.send_msg(LATCP_CMD_TERMINALSESSION, '%c%c%s%c%s%c%s%c%s%c%s' % \
67 len(service), service,
70 len(localport), localport,
71 len(password), password
73 (cmd, msg) = self.read_reply()
74 if ord(cmd) == LATCP_CMD_ERRORMSG:
75 raise LATClientException(msg)
77 self.rfh = self.sock.makefile('r')
78 self.wfh = self.sock.makefile('w')
80 r = select([self.rfh], [], [], 2.0)[0]
82 l = self.rfh.readline()
83 if l.find('Service in use') >= 0:
84 logging.warning("Service in use, apparently: restarting DEC server")
95 def send_msg(self, cmd, msg):
96 self.sock.send('%c%c%c%s'%(cmd, len(msg)/256, len(msg)%256, msg))
98 def reboot_server(self):
102 logging.info('Logging into DEC server')
103 mopw, mopr = popen4('/usr/sbin/moprc '+self.server_name)
104 write_and_get_response(mopr, mopw, '')
106 logging.info('Sending password')
107 r = write_and_get_response(mopr, mopw, self.connect_password, False)
108 if r.find('Enter username> ') == -1:
109 logging.warning("Expected username prompt, got " + repr(r))
110 raise LATClientException('failed to reboot server')
112 logging.info('Sending username')
113 r = write_and_get_response(mopr, mopw, 'grim reaper')
114 if r.find('Local> ') == -1:
115 logging.warning("Expected DEC server prompt, got " + repr(r))
116 raise LATClientException('failed to reboot server')
118 logging.info('Requesting privileges')
119 r = write_and_get_response(mopr, mopw, 'set priv')
120 if r.find('Password> ') == -1:
121 logging.warning("Expected priv password prompt, got " + repr(r))
122 raise LATClientException('failed to reboot server')
124 logging.info('Sending password')
125 r = write_and_get_response(mopr, mopw, self.priv_password, False)
126 if r.find('Local> ') == -1:
127 logging.warning("Expected DEC server prompt, got " + repr(r))
128 raise LATClientException('failed to reboot server')
130 logging.info('Sending reboot request')
131 r = write_and_get_response(mopr, mopw, 'init del 0')
132 if r.find('Target does not respond') == -1:
133 logging.warning("Expected DEC server to die, got " + repr(r))
134 raise LATClientException('failed to reboot server')
136 logging.info('Closed connection to server')
139 logging.info("Waiting 10 seconds for DEC server to come back to life...")
141 logging.info("Rightyo, back to vending!")
142 raise LATClientException('needed to reboot server')
144 def read_reply(self):
145 head = self.sock.recv(3)
147 raise LATClientException('Short LAT packet')
149 length = ord(head[1])*256 + ord(head[2])
150 msg = self.sock.recv(length)
151 if cmd == LATCP_CMD_ERRORMSG:
152 raise LATClientException('Received LAT error: %s'%msg)
156 return (self.rfh, self.wfh)