/examples/telnet.py

https://bitbucket.org/prologic/circuits/ · Python · 172 lines · 88 code · 42 blank · 42 comment · 17 complexity · 5592be405552cbfe8565c79048a02640 MD5 · raw file

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