/examples/telnet.py
Python | 172 lines | 88 code | 42 blank | 42 comment | 13 complexity | 5592be405552cbfe8565c79048a02640 MD5 | raw file
1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4 5"""Telnet Example 6 7A basic telnet-like clone that connects to remote hosts 8via tcp and allows the user to send data to the remote 9server. 10 11This example demonstrates: 12 * Basic Component creation. 13 * Basic Event handling. 14 * Basiv Networking 15 * Basic Request/Response Networking 16 17This example makes use of: 18 * Component 19 * Event 20 * net.sockets.TCPClient 21""" 22 23 24from __future__ import print_function 25 26import os 27from optparse import OptionParser 28 29 30import circuits 31from circuits.io import stdin 32from circuits.tools import graph 33from circuits import handler, Component 34from circuits.net.events import connect, write 35from circuits.net.sockets import TCPClient, UNIXClient, UDPClient 36 37 38USAGE = "%prog [options] host [port]" 39VERSION = "%prog v" + circuits.__version__ 40 41 42def parse_options(): 43 parser = OptionParser(usage=USAGE, version=VERSION) 44 45 parser.add_option( 46 "-u", "--udp", 47 action="store_true", default=False, dest="udp", 48 help="Use UDP transport", 49 ) 50 51 parser.add_option( 52 "-v", "--verbose", 53 action="store_true", default=False, dest="verbose", 54 help="Enable verbose debugging", 55 ) 56 57 opts, args = parser.parse_args() 58 59 if len(args) < 1: 60 parser.print_help() 61 raise SystemExit(1) 62 63 return opts, args 64 65 66class Telnet(Component): 67 68 # Define a separate channel for this component so we don't clash with 69 # the ``read`` event of the ``stdin`` component. 70 channel = "telnet" 71 72 def __init__(self, *args, **opts): 73 super(Telnet, self).__init__() 74 75 self.args = args 76 self.opts = opts 77 78 if len(args) == 1: 79 if os.path.exists(args[0]): 80 UNIXClient(channel=self.channel).register(self) 81 host = dest = port = args[0] 82 dest = (dest,) 83 else: 84 raise OSError("Path %s not found" % args[0]) 85 else: 86 if not opts["udp"]: 87 TCPClient(channel=self.channel).register(self) 88 else: 89 UDPClient(0, channel=self.channel).register(self) 90 91 host, port = args 92 port = int(port) 93 dest = host, port 94 95 self.host = host 96 self.port = port 97 98 print("Trying %s ..." % host) 99 100 if not opts["udp"]: 101 self.fire(connect(*dest)) 102 else: 103 self.fire(write((host, port), b"\x00")) 104 105 def ready(self, *args): 106 graph(self.root) 107 108 def connected(self, host, port=None): 109 """connected Event Handler 110 111 This event is fired by the TCPClient Componentt to indicate a 112 successful connection. 113 """ 114 115 print("connected to {0}".format(host)) 116 117 def error(self, *args, **kwargs): 118 """error Event Handler 119 120 If any exception/error occurs in the system this event is triggered. 121 """ 122 123 if len(args) == 3: 124 print("ERROR: {0}".format(args[1])) 125 else: 126 print("ERROR: {0}".format(args[0])) 127 128 def read(self, *args): 129 """read Event Handler 130 131 This event is fired by the underlying TCPClient Component when there 132 is data to be read from the connection. 133 """ 134 135 if len(args) == 1: 136 data = args[0] 137 else: 138 peer, data = args 139 140 data = data.strip().decode("utf-8") 141 142 print(data) 143 144 # Setup an Event Handler for "read" events on the "stdin" channel. 145 @handler("read", channel="stdin") 146 def _on_stdin_read(self, data): 147 """read Event Handler for stdin 148 149 This event is triggered by the connected ``stdin`` component when 150 there is new data to be read in from standard input. 151 """ 152 153 if not self.opts["udp"]: 154 self.fire(write(data)) 155 else: 156 self.fire(write((self.host, self.port), data)) 157 158 159def main(): 160 opts, args = parse_options() 161 162 # Configure and "run" the System. 163 app = Telnet(*args, **opts.__dict__) 164 if opts.verbose: 165 from circuits import Debugger 166 Debugger().register(app) 167 stdin.register(app) 168 app.run() 169 170 171if __name__ == "__main__": 172 main()