Example #1
0
 def telnet_recv(fds):
     """
     test all telnet clients with file descriptors in list fds for
     recv(). If any are disconnected, signal exit to subprocess,
     unregister the session (if any).
     """
     # read in any telnet input
     for client in (clt for (fno, clt) in telnetd.clients.iteritems()
                    if fno in fds):
         try:
             client.socket_recv()
         except Disconnected as err:
             logger.info('%s Connection Closed: %s.',
                         client.addrport(), err)
             tty = lookup(client)
             if tty is None:
                 # no session found, just de-activate this client
                 client.deactivate()
             else:
                 # signal exit to sub-process and shutdown
                 send_event, send_data = 'exception', Disconnected(err)
                 tty.iqueue.send((send_event, send_data))
                 unregister(tty)
Example #2
0
 def telnet_send(recv_list):
     """
     test all telnet clients for send(). If any are disconnected,
     signal exit to subprocess, unregister the session, and return
     recv_list pruned of their file descriptors.
     """
     for sid, tty in terminals():
         if tty.client.send_ready():
             try:
                 tty.client.socket_send()
             except Disconnected as err:
                 logger.debug('%s Disconnected: %s.', sid, err)
                 # client.sock.fileno() can raised 'bad file descriptor',
                 # so, to remove it from the recv_list, reverse match by
                 # instance saved with its FD as a key for telnetd.clients!
                 for _fd, _client in telnetd.clients.items():
                     if tty.client == _client:
                         if _fd in recv_list:
                             recv_list.remove(_fd)
                         break
                 send_event, send_data = 'exception', Disconnected(err)
                 tty.iqueue.send((send_event, send_data,))
                 unregister(tty)
     return recv_list
Example #3
0
    def session_recv(fds):
        """
        receive data waiting for session; all data received from
        subprocess is in form (event, data), and is handled by ipc_recv.

        if stale is not None, elapsed time lock was held to consider stale
        and acquire anyway. no actual locks are held or released, just a
        simple dictionary state/time tracking system.
        """

        disp_handle = lambda handle: ((handle + u' ')
                                      if handle is not None
                                      and 0 != len(handle) else u'')
        disp_origin = lambda client: client.addrport().split(':', 1)[0]

        for sid, tty in terminals():
            while tty.oqueue.fileno() in fds and tty.oqueue.poll():
                # receive data from pipe, unregister if any error,
                try:
                    event, data = tty.oqueue.recv()
                except (EOFError, IOError) as err:
                    # sub-process unexpectedly closed
                    logger.exception(err)
                    unregister(tty)
                    return
                # 'exit' event, unregisters client
                if event == 'exit':
                    unregister(tty)
                    return
                # 'logger' event, propogated upward
                elif event == 'logger':
                    # prefix message with 'ip:port/nick '
                    data.msg = '%s[%s] %s' % (
                        disp_handle(data.handle),
                        disp_origin(tty.client),
                        data.msg)
                    logger.handle(data)
                # 'output' event, buffer for tcp socket
                elif event == 'output':
                    tty.client.send_unicode(ucs=data[0], encoding=data[1])
                # 'remote-disconnect' event, hunt and destroy
                elif event == 'remote-disconnect':
                    send_to = data[0]
                    for _sid, _tty in terminals():
                        if send_to == _sid:
                            send_event = 'exception'
                            send_val = Disconnected(
                                'remote-disconnect by %s' % (sid,))
                            tty.iqueue.send((send_event, send_val))
                            unregister(tty)
                            break
                # 'route': message passing directly from one session to another
                elif event == 'route':
                    logger.debug('route %r', (event, data))
                    tgt_sid, send_event, send_val = data[0], data[1], data[2:]
                    for _sid, _tty in terminals():
                        if tgt_sid == _sid:
                            _tty.iqueue.send((send_event, send_val))
                            break
                # 'global': message broadcasting to all sessions
                elif event == 'global':
                    logger.debug('broadcast %r', (event, data))
                    for _sid, _tty in terminals():
                        if sid != _sid:
                            _tty.iqueue.send((event, data,))
                # 'set-timeout': set user-preferred timeout
                elif event == 'set-timeout':
                    logger.debug('set-timeout %d', data)
                    tty.timeout = data
                # 'db*': access DBProxy API for shared sqlitedict
                elif event.startswith('db'):
                    thread = DBHandler(tty.iqueue, event, data)
                    thread.start()
                # 'lock': access fine-grained bbs-global locking
                elif event.startswith('lock'):
                    handle_lock(tty, event, data)
                else:
                    assert False, 'unhandled %r' % ((event, data),)